Существуют разные типы умных указателей, предназначенных для разных целей.Указатель, о котором вы говорите, - это общий интеллектуальный указатель (std::shared_ptr
), который позволяет совместно использовать владение объектами из разных мест.Все копии shared_ptr
увеличивают и уменьшают одну и ту же переменную счетчика, которая помещается в кучу, поскольку она должна быть доступна для всех копий shared_ptr
даже после смерти первой копии.
Такshared_ptr
внутренне сохраняет два указателя: на объект и на счетчик.Псевдокод:
class SharedPointer<T> {
public:
// ...
private:
T* obj;
int* counter;
}
Кстати, когда вы создаете объект с std::make_shared
, реализация может оптимизировать выделения, выделяя достаточно памяти для хранения как счетчика, так и объекта, а затем создавая их рядом друг с другом.
Этот трюк в крайности дает нам навязчивую схему подсчета ссылок: объект внутренне удерживает свой счетчик и предоставляет функции AddRef
и Release
для увеличения и уменьшения его.Вы можете использовать навязчивый умный указатель , например boost::intrusive_ptr
, который использует этот механизм и, следовательно, не нуждается в выделении другого отдельного счетчика.Это быстрее с точки зрения распределения, но требует внедрения счетчика в определение управляемого класса.
Кроме того, когда вам не нужно совместно использовать владение объектом и нужно только контролировать его время жизни (так что оно разрушаетсякогда функция возвращается), вы можете использовать умный указатель : std::unique_ptr
или boost::scoped_ptr
.Счетчик вообще не нужен, так как существует только одна копия unique_ptr
.