Пространства имён
Варианты
Действия

std::enable_shared_from_this

Материал из cppreference.com
< cpp‎ | memory
 
 
 
Динамическое управление памятью
Низкоуровневое управление памятью
Аллокаторы
allocator
allocator_traits(C++11)
allocator_arg_t(C++11)
allocator_arg(C++11)
uses_allocator(C++11)
scoped_allocator_adaptor(C++11)
Неинициализированные хранилища
uninitialized_copy
uninitialized_copy_n(C++11)
uninitialized_fill
uninitialized_fill_n
raw_storage_iterator
get_temporary_buffer
return_temporary_buffer
Умные указатели
unique_ptr(C++11)
shared_ptr(C++11)
weak_ptr(C++11)
auto_ptr(устарело)
owner_less(C++11)
enable_shared_from_this(C++11)
bad_weak_ptr(C++11)
default_delete(C++11)
Поддержка сборки мусора
declare_reachable(C++11)
undeclare_reachable(C++11)
declare_no_pointers(C++11)
undeclare_no_pointers(C++11)
pointer_safety(C++11)
get_pointer_safety(C++11)
Разное
pointer_traits(C++11)
addressof(C++11)
align(C++11)
Библиотека C
 
std::enable_shared_from_this
 
Определено в заголовочном файле <memory>
template< class T > class enable_shared_from_this;
(начиная с C++11)

std::enable_shared_from_this позволяет объекту t, который управляется умным указателем pt с типом std::shared_ptr, безопасно создать дополнительные экземпляры pt1, pt2, ... с типом std::shared_ptr, такие, что все они будут раздельно владеть объектом t, наравне с pt.

Наследование от std::enable_shared_from_this<T> предоставляет тип T с функцией-членом shared_from_this. Если объект t типа T управляется умным указателем pt с типом std::shared_ptr<T>, то вызов T::shared_from_this вернет созданный std::shared_ptr<T>, который будет разделять владение объектом t, наравне с pt.

Обратите внимание, что перед вызовом shared_from_this для объекта t, должен существовать std::shared_ptr, который владеет t.

Также нужно отметить, что enable_shared_from_this предоставляет альтернативу выражению std::shared_ptr<T>(this), которое может привести к уничтожению this более одного раза несколькими владеющими указателями, которые не обладают информацией о наличии друг друга.

Содержание

[править] Функции-члены

создает объект enabled_shared_from_this
(protected функция-член)
уничтожает enable_shared_from_this
(protected функция-член)
возвращает ссылку на this
(protected функция-член)
возвращает shared_ptr, который разделяет владение *this
(public функция-член)

[править] Заметки

Обычная реализация enable_shared_from_this сводится к хранению слабой ссылки (к примеру, std::weak_ptr) на this. Конструкторы std::shared_ptr способны обнаружить наличие базового класса enable_shared_from_this и разделить владение объектом с уже существующими указателями std::shared_ptr, вместо того, чтобы решить, что указатель больше ничем не управляется.

[править] Пример

#include <memory>
#include <iostream>
 
struct Good: std::enable_shared_from_this<Good>
{
    std::shared_ptr<Good> getptr() {
        return shared_from_this();
    }
};
 
struct Bad {
    std::shared_ptr<Bad> getptr() {
        return std::shared_ptr<Bad>(this);
    }
    ~Bad() { std::cout << "Bad::~Bad() called\n"; }
};
 
int main()
{
    // Хорошо: два указателя shared_ptr владеют одним и тем же объектом
    std::shared_ptr<Good> gp1(new Good);
    std::shared_ptr<Good> gp2 = gp1->getptr();
    std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';
 
    // Плохо: каждый указатель shared_ptr думает, что он единственный владелец объекта
    std::shared_ptr<Bad> bp1(new Bad);
    std::shared_ptr<Bad> bp2 = bp1->getptr();
    std::cout << "bp2.use_count() = " << bp2.use_count() << '\n';
} // Неопределенное поведение: двойное удаление Bad

Вывод:

gp2.use_count() = 2
bp2.use_count() = 1
Bad::~Bad() called
Bad::~Bad() called
*** glibc detected *** ./test: double free or corruption

[править] См. также

умный указатель разделяемого владения объектом
(шаблон класса) [edit]