Средство удаления связано с принадлежащим объектом и будет использоваться для его удаления, когда последний владелец удаляет его ссылку, поэтому все указатели, которые совместно владеют одним и тем же объектом, также используют средство удаления. Средство удаления не хранится в отдельных объектах shared_ptr
, оно хранится в куче вместе со счетчиками ссылок, поэтому используется всеми объектами, имеющими одни и те же счетчики.
Итак, давайте посмотрим на ваш код. Во-первых, мне пришлось исправить ваш код, так как он даже не скомпилировался, как показано. Всегда полезно протестировать код в вашем вопросе, чтобы не тратить время людей, заставляя их исправлять опечатки и добавлять отсутствующие заголовки.
Не пишите это:
B * b0 = new B;
boost::shared_ptr < B > sddb0(b0, doNothing);
Правильный способ сделать это:
boost::shared_ptr < B > sddb0(new B, doNothing);
База enable_shared_from_this<B>
имеет член weak_ptr<B>
, который назначается конструктором shared_ptr
, так что weak_ptr
разделяет владение с sddb0
, как и общий указатель, возвращаемый shared_from_this()
.
Итак, ответ на этот вопрос — да:
// Does this have a custom deleter???
boost::shared_ptr < B > sddb1 = swddb0.lock();
sddb1
разделяет право собственности с sddb0
, поэтому у него один и тот же инструмент для удаления.
Вы можете проверить это, используя get_deleter
, или записав stdout
в doNothing
, или используя owner_less
для сравнения владельцев указателей.
Это создает объект, который не разделяет владение с существующими общими указателями:
boost::shared_ptr ‹ B > scdb0(b0);
Член weak_ptr<B>
базы enable_shared_from_this<B>
переназначается строкой выше, поэтому он разделяет владение с scdb0
вместо sddb0
. Поэтому, когда вы вызываете get_weak
после этого момента, он возвращает слабый указатель, который разделяет владение с scdb0
и поэтому не имеет специального удаления. Опять же, вы можете легко убедиться в этом, увидев, что doNothing
не вызывается, или используя owner_less
.
person
Jonathan Wakely
schedule
28.07.2012