Почему указатели в надстройке

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

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();
}
Другие вопросы по тегам