Страницы

Поиск по вопросам

среда, 3 октября 2018 г.

Умные указатели shared_ptr и weak_ptr, отношение родитель и потомок

Насколько я понимаю, типичное использование weak_ptr такое:
class Child { private : weak_ptr mParent ; } ;
class Parent: public enable_shared_from_this { private : shared_ptr mChild ; };
Т.е. родитель владеет потомком и потомок будет уничтожен при уничтожении родителя.
А существуют ли случаи, когда удобнее делать наоборот?
class Child { private : shared_ptr mParent ; } ;
class Parent: public enable_shared_from_this { private : weak_ptr mChild ; };


Ответ

Конечно бывают. В основном когда родитель представляет собой большой ресурс, а дети представляют доступ к частям этого ресурса. При этом освобождение ресурса выполняет родитель. Например, под этот случай подойдет куча из WinApi. Родитель будет содержать дескриптор кучи, а дочерние объекты - указатели на блоки памяти выделеные из этой кучи. Если мы освободим объект кучи, то указатели станут невалидными, поэтому необходимо следить за порядком освобождения. Собственно, логично возложить эту работу на стандартные классы.
Кстати, у std::shared_ptr есть конструктор, (номер 8 по ссылке) ориентированный на подобный шаблон:
template< class Y > shared_ptr( const shared_ptr& r, T * ptr );
Здесь предполагается что r - это родитель, а ptr - ребенок. При этом доступ будет предоставлен к указателю ptr, но при удалении умного указателя будет освобождён r. Вот примерный сценарий:
struct Parent { int Child; };
auto parent = std::make_shared(); auto child = std::shared_ptr(parent, &parent->Child);
parent->Child = 10; bool is_ten = *child == 10; // OK
parent = nullptr; // Parent не удален, он продолжает жить в child *child = 11; // OK child = nullptr; // а вот теперь Parent удаляется

Комментариев нет:

Отправить комментарий