Важно
Пожалуйста, помните, что std::auto_ptr
имеет много недостатков, и вам, как правило, следует использовать std::unique_ptr
, если ваш компилятор предоставляет это. (Если этого не произойдет, обновите ваш компилятор! :))
Теперь вернемся к вашему вопросу ...
Какой смысл использовать этот auto_ptr? Он вызывает деструктор класса при выходе из области видимости как обычная переменная инициализации класса (a)
Точно. Причина auto_ptr
состоит в том, чтобы обеспечить строгую семантику владения, чтобы объект уничтожался должным образом при уничтожении самого указателя.
Я не могу передать этот указатель на функцию с указателем класса (func)
Вы можете, вам нужно использовать get()
, чтобы найти необработанный указатель. Использование get()
при передаче указателя на вызов функции означает, что функция не собирается вступать во владение объектом (auto_ptr
все еще владеет им и ожидает, что он все еще действителен после возврата функции).
В качестве альтернативы, вы можете использовать release()
на указателе, чтобы получить необработанный указатель И указать, что auto_ptr
больше не отвечает за владение объектом.
Я не могу использовать указатель auto_ptr для A [] или char [], потому что auto_ptr вызывает delete not delete []
Да, это проблема. Это одна из причин, по которой больше не используется auto_ptr
с момента появления unique_ptr
. Он делает то же самое, но безопаснее (= проще) и более универсален.
Единственная мысль - мне не нужно писать delete, но какой смысл в указателе, если он исчезнет, когда я выйду из области видимости.
Так что вы не забудете это :-) Или вы можете использовать auto_ptr
(или лучше unique_ptr
в качестве члена в объекте класса).
но скажите, в чем смысл использовать auto_ptr вместо обычного указателя?
Короче говоря: многие указатели могут указывать на один объект. Существуют все виды интеллектуальных указателей для использования системы типов для учета, указатель которой владеет объектом (= отвечает за его освобождение).
примечание
Если у вас есть класс, который (может) владеть экземпляром другого объекта, вы просто пишете:
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) { ptr.reset(ptr); }
// ...
std::unique_ptr<Type> ptr;
};
Если установлено ptr
, то, например, деструктор unique_ptr
позаботится об удалении объекта (если он есть). В методе setPtr
функция reset()
удаляет старый экземпляр (если он есть) и устанавливает для члена новый предоставленный экземпляр (или ноль - это нормально).
Теперь сравните другую ситуацию:
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) {delete ptr; ptr = ptr2;}
// ...
Type* ptr;
};
Такое же поведение? Нет! Потому что теперь, чтобы иметь безопасный код C ++, вам дополнительно нужно написать деструктор для удаления ptr
при уничтожении X
.
Хорошо, теперь? НЕТ! Поскольку, поскольку у вас есть общий деструктор, вам нужно свернуть (или заблокировать) свой собственный конструктор копирования и оператор присваивания, потому что в противном случае вы могли бы в конечном итоге получить два экземпляра X, указывающих на один и тот же объект Type, - и оба экземпляра здесь думают, что им принадлежит этот экземпляр, и оба они когда-нибудь попытаются его удалить. Бум, нарушение доступа.
Unique_ptr не позволит вам неявно копировать объект X вместе со строгой ссылкой на ptr
, потому что unique_ptr не копируется (он считает, что это единственный unique_ptr для объекта, поэтому он является единственным интеллектуальным экземпляр указателя, ответственный за его удаление - но это нормально, если на него указывают необработанные указатели, не являющиеся владельцами, если они не пытаются удалить то, что им не принадлежит!).
И это еще не все - unique_ptr не может быть скопирован, но у него есть конструктор перемещения и оператор присваивания перемещения, готовый для вас! Следовательно, вы можете безопасно вернуть его из функций и т. Д.
Вот как безопасность типов умных указателей переходит на написание более безопасного кода.
Золотое правило: старайтесь избегать написания «удалить» (если вы не пишете свои собственные контейнеры или умные указатели). :)