Действительно ли enable_shared_from_this обеспечивает ту же оптимизацию? Итак:
No. Как видно из формулировки стандарта, enable_shared_from_this<T>
имеет элемент в weak_ptr<T>
данных. Это добавляет weak_ptr<T>
к классу, который имеет указатель на блок управления, содержащий количество ссылок. Он не содержит счетчики ссылок напрямую. Блок управления, содержащий ссылочные счеты, по-прежнему существует вне объекта.
Контрольный блок, содержащий ссылочные подсчеты, должен пережить объект, так что другие объекты weak_ptr
, которые использовали для ссылки на объект, могут получить доступ к блоку управления, чтобы проверить, истек ли он.
Если контрольный блок находился внутри объекта, он был бы уничтожен, когда объект был уничтожен, и было бы невозможно, чтобы оборванный weak_ptr
безопасно определял, истек ли объект. Теоретически память блока управления может оставаться выделенной и все еще использоваться, а контрольные подсчеты обновляются, хотя объект, из которого они были частью, был уничтожен, но это кажется довольно уродливым (и это будет означать, что объект не будет уничтожен с помощью delete
, для этого потребуется явный вызов деструктора и явный вызов operator delete
, чтобы освободить память).
Вы также не могли использовать встроенный блок управления, если владелец shared_ptr
был создан с помощью пользовательского делетера или настраиваемого распределителя, поскольку размер этих объектов не был бы заранее известен. В таких случаях вам еще нужно будет выделить внешний блок управления в дополнение к, который был встроен в базовый класс enable_shared_from_this<T>
, тратя еще больше места.
Эти два полностью ортогональны. 'enable_shared_from_this' имеет значение, если вы уже имеете * общий указатель. –
@KerrekSB Я полагаю, что enable_shared_from_this добавляет некоторые данные в класс, который может использоваться при реализации общего указателя. Что касается меня, то самый простой способ - разместить количество ссылок как часть enable_shared_from_this, и это может помочь уменьшить выделение памяти в первом случае. –
У меня возникает соблазн сказать «да», так как в противном случае невозможно извлечь блок refcount изнутри объекта. Но это просто догадка. – Quentin