2010-04-16 5 views
6

В одном из моих проектов у меня есть несколько классов, которые представляют собой объекты, которые не могут измениться после создания, ака. неизменяемые классы.Неизменяемые классы в C++

Пример: класс RSAKey, представляющий ключ RSA, который имеет только методы const. Нет смысла менять существующий экземпляр: если вам нужен другой, вы просто создаете его.

Мои объекты иногда тяжелые, и я применял использование умных указателей, чтобы избежать deep копия.

До сих пор, у меня есть следующий образец для моих классов:

class RSAKey : public boost::noncopyable, public boost::enable_shared_from_this<RSAKey> 
{ 
    public: 

    /** 
    * \brief Some factory. 
    * \param member A member value. 
    * \return An instance. 
    */ 
    static boost::shared_ptr<const RSAKey> createFromMember(int member); 

    /** 
    * \brief Get a member. 
    * \return The member. 
    */ 
    int getMember() const; 

    private: 

    /** 
    * \brief Constructor. 
    * \param member A member. 
    */ 
    RSAKey(int member); 

    /** 
    * \brief Member. 
    */ 
    const int m_member; 
}; 

Таким образом, вы можете получить только указатель (ну, указатель умного) к константной RSAKey. Для меня это имеет смысл, потому что наличие неконстантной ссылки на экземпляр бесполезно (оно имеет только методы const).

Вы, ребята, видите какую-либо проблему в отношении этого шаблона? Являются ли неизменяемые классы чем-то распространенным в C++ или я только что создал монстра?

Благодарим вас за советы!

+1

Одно из предложений: если ваш класс не подлежит копированию и неизменен, вы также можете сделать 'm_member' const. –

+0

Спасибо. Это const в моем коде. Я забыл об этом, когда написал этот пример. Отредактировано;) – ereOn

+0

Просто будьте осторожны при использовании 'boost :: shared_ptr' не для создания более одного общего указателя с использованием того же' RSAKey * ', либо они не будут разделять право собственности на объект друг с другом и будут удалены, если все еще есть общие указатели, ссылающиеся на него. По этой причине я бы действительно препятствовал использованию 'boost :: shared_ptr', если вы действительно не знаете, что вы делаете, и используйте общий класс указателей, который вместо этого хранит контрольный счетчик внутри объектов (например, Qt или создайте свой собственный). – HelloGoodbye

ответ

1

Выглядит хорошо для меня.

Маркировка каждого объекта const с фабрики устраняет маркировку каждого элемента данных const, но в этом примере только один.

+1

@Potatoswatter, почему ваш ответ * wiki сообщества *? (Я даже не знал, что ответы могут быть * вики сообщества * сами по себе). Просто интересуюсь. – ereOn

+0

@ereOn: Потому что я не чувствую, что что-то вносит. Если кто-то хочет добавить фактический контент к моему сообщению, не стесняйтесь. Это скорее манекен, поэтому вы можете согласиться с тем, что вы правы в конце. – Potatoswatter

9

Это похоже на перебор. Когда у вас есть только константные члены, объект не может быть изменен в любом случае. Если вы хотите запретить копирование, просто создайте конструктор копирования и оператор присваивания.

+0

Это уже сделано путем наследования от boost :: noncopyable. – ereOn

+5

boost: noncopyable более явный. Посмотрев на интерфейс, вы сразу увидите «: public boost :: noncopyable», в то время как вы можете не заметить конструктор частной копии и оператор присваивания. –

+1

Но это приводит к значительным накладным расходам Boost, когда совершенно хорошая идиома, скрывающая конструктор копирования и оператор копирования, уже существует. Какая польза для программиста? (Преимущества для промоутеров Boost очевидны) – DannyT

Смежные вопросы