Почему указатели в надстройке
Какова цель указателя в области видимости? насколько я понимаю, указатель с областью действия управляет памятью в блоке кода. Если я хочу объявить переменную внутри блока, я могу просто объявить ее в стеке и не беспокоиться об очистке.
4 ответа
Нет, если он имеет динамический размер или тип. Кроме того, указатели области видимости можно поменять местами, а в C++11 unique_ptr
могут быть перемещены, поэтому они не строго ограничены.
В отличие от стековых данных, scoped_ptr имеет элемент reset() - иными словами, вы можете создавать / разрушать содержимое вашего сердца. При этом вы можете использовать нулевой указатель (технически operator unspecified-bool-type
) как флаг, указывающий, существует ли построенный объект в любой момент времени. Это также позволяет вам последовательно строить / уничтожать независимо от области видимости переменной, если это необходимо.
Также учтите, что вы можете объявить scoped_ptr как член класса, а не только как переменную стека. В документах предлагается использовать scoped_ptr для реализации идиомы handle / body (чтобы скрыть детали реализации класса).
Наконец, чтобы развить пункт DeadMG "Нет, если он динамического типа", вы можете использовать scoped_ptr для реализации полиморфной операции:
{
scoped_ptr<Base> a( mode ? new DerivedA : new DerivedB );
a->polymorphic_function();
}
На самом деле это невозможно сделать простым распределением на основе стека.
Также см. Здесь: C++ 0x unique_ptr заменяет scoped_ptr, вступая во владение?
Дело в том, что вы можете создавать и очищать указатель в определенной лексической области видимости. Это может быть полезно в различных ситуациях и гарантирует отсутствие утечек памяти, если вы забудете delete
если бы вы были использовать new
явно, что не рекомендуется.
Вы должны иметь в виду, что boost::scoped_ptr
не подлежит копированию и поэтому полностью владеет своим ресурсом на протяжении всего срока его службы. Это также делает его более безопасным, чем boost::shared_ptr
, поскольку это позволяет избежать копирования ресурса или случайного обмена им.
{ //Some Scope
boost::scoped_ptr<int> i_ptr;
// do something with pointer
} // leave scope, pointer is cleaned up
Обычно стеки потоков имеют ограничения памяти (см. размер стека потоков).
также иногда указатель мог быть передан вам извне и должен быть удален в этой области (например, если выдается исключение, любой вызов удаления ниже этой строки не будет выполнен). Так что вам нужно как-то автоматически очистить указатель
void foo(Object*obj)
{
//this will ensure that object gets cleaned up even if doFoo() throws an exception
boost::scoped_ptr<Object> objCleaner(obj);
obj->doFoo();
}