Какой неразделенный Smart Pointer для переменных членов класса - PullRequest
1 голос
/ 14 октября 2010

Когда у меня есть класс, который содержит указатели в качестве переменных-членов, какой тип интеллектуального указателя они должны иметь, если я не хочу использовать простые указатели? Они не должны быть разделены (поэтому не требуется shared_ptr). scoped_ptr не будет работать, так как мне часто приходится создавать объекты вне списка инициализации.

Или может быть обычной практикой является использование scoped_ptr во время создания, когда что-то все еще может потерпеть неудачу (исключения создаются и т. Д.), А затем назначать их простым указателям?

Ответы [ 3 ]

4 голосов
/ 14 октября 2010

Если вы просто хотите сохранить указатели на элементы в классе интеллектуальных указателей, чтобы вы не могли / не забудете их удалить, тогда стандартным выбором будет auto_ptr. Он находится в STL и легко «сбрасывается» с помощью функции reset(), когда вам нужно освободить текущую выделенную ему память и заменить ее новым объектом.

Вы все еще захотите реализовать свой собственный конструктор копирования и операторы присваивания для классов, которые имеют члены auto_ptr. Это связано с тем, что оператор присваивания auto_ptrs передает владение базовым объектом, поэтому оператор присваивания по умолчанию не даст желаемого эффекта.

Вот как может выглядеть класс:

class X
{
public:
    X() :p(new ClassToManage) {}
    X(const X &copy)
        :p(new ClassToManage(*copy.p))
    {
    }

    X &operator=(const X &rhs)
    { 
        this->p.reset(new ClassToManage(*rhs.p));   
    }   

private:
    std::auto_ptr<ClassToManage> p;
};

Для всех остальных случаев я бы предложил boost::shared_ptr. Shared_ptr выполняет подсчет ссылок, но вы можете хранить их в стандартных контейнерах, что делает их весьма полезными.

В конечном итоге вы должны попытаться избавиться от использования простых указателей для всего, что указывает на выделенную память, за которую он отвечает за удаление. Если вы хотите использовать простой указатель для доступа или итерации по простому массиву ole и т. Д., Тогда это нормально (но спросите себя, почему вы не используете std :: vector), но когда вы используете их, чтобы указать на что-то, что он отвечает за освобождение, тогда вы напрашиваетесь на неприятности. Моя цель при написании кода - не удалять явно.

1 голос
/ 14 октября 2010

Вы можете использовать std::auto_ptr, который был доступен до TR1, и поэтому ваш код не зависит от компилятора, поддерживающего TR1-smartpointers.

0 голосов
/ 14 октября 2010

Обычно я использую deep_copy_ptr. Прямо сейчас я знаю о loki smart_ptr и умном указателе axter, которые делают это. Это позволяет автоматически копировать класс указателя, как если бы это была обычная переменная-член (вам не нужно определять специальный оператор присваивания / конструктор копирования).

Я думаю, вам не нужно специально инициализировать его в списке инициализаторов (но, как обычный указатель, не используйте его, если у него нет действительного значения, очевидно).

...