Какой неразделенный Smart Pointer для переменных членов класса

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

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

3 ответа

Решение

Если вы просто хотите хранить указатели на элементы в классе интеллектуальных указателей, чтобы вы не могли / не забудете их удалить, тогда стандартным выбором будет 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), но когда вы используете их, чтобы указать на что-то, что он отвечает за освобождение, тогда вы напрашиваетесь на неприятности. Моя цель при написании кода - не удалять явно.

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

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

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

Другие вопросы по тегам