есть ли способ использовать enable_shard_from_this
как отношение "имеет" вместо отношения "является"?
No.
enable_shared_from_this
предполагается использоваться в качестве базового класса, поэтому бездумное применение рекомендаций, предназначенных для других ситуаций, в данном случае не работает.
Даже если бы была веская причина хотеть это сделать (а ее нет), это не сработало бы. Волшебство, которое заставляет базу enable_shared_from_this
делить владение с shared_ptr
, которому принадлежит производный объект, работает путем проверки наследования.
enable_shared_from_this
в любом случае не моделирует отношения IS-A, потому что у него нет интерфейса, определенного в терминах виртуальных функций. IS-A означает производный тип, который расширяет базовый интерфейс, но здесь это не так. А Good
ЕСТЬ-НЕ-А enable_shared_from_this<Good>
.
т. е. использование наследования не всегда подразумевает отношение IS-A.
- enable_shared_from_this не имеет виртуального деструктора
Виртуальный деструктор не имеет значения, если только вы не планируете удалять объект через указатель на базовый класс enable_shared_from_this
, что было бы безумием. Нет причин когда-либо передавать Good
в качестве указателя на базовый класс enable_shared_from_this<Good>
, и еще меньше причин когда-либо использовать delete
для этого базового указателя (обычно тип будет сохранен в shared_ptr<Good>
, как только он будет создан, так что вы вообще никогда не используйте delete
).
enable_shared_from_this
— это тип примеси, а не абстрактная база. Он предоставляет shared_from_this
(а вскоре и weak_from_this
) члена, вот и все. Вы не должны использовать его как абстрактный базовый или тип интерфейса, а также использовать базовый тип для доступа к полиморфному поведению производного типа. Тот факт, что он вообще не имеет виртуальных функций, а не только виртуального деструктора, должен вам об этом сказать.
Кроме того, как н.м. прокомментировано выше, деструктор защищен, поэтому вы не можете удалить его через базовый класс, даже если попытаетесь (защищенный деструктор — это идиоматический способ предотвращения неправильного использования классов примесей, предназначенных для неполиморфные базовые классы).
- Деструктор
enable_shared_from_this
уничтожает *this
, то есть он всегда должен вызываться последним деструктором.
Хм? Не уверен, что вы имеете в виду, но он не несет ответственности за уничтожение чего-либо, кроме себя и своего собственного члена данных.
- Наследование от двух классов, которые оба наследуют от
enable_shared_from_this
, может стать камнем преткновения.
Это должно работать нормально (хотя вы можете не получить волшебное совместное владение, если нет ни одного однозначного базового класса, который является специализацией enable_shared_from_this
). В стандартной библиотеке GCC была ошибка (сейчас исправлена), из-за которой она не могла скомпилироваться, а не просто не могла разделить владение, но это не проблема с enable_shared_from_this
.
person
Jonathan Wakely
schedule
02.12.2015
enable_shared_from_this
; естьenable_shared_from_this<D>
. Это важно. ЕслиA
происходит отenable_shared_from_this<A>
, аB
происходит отenable_shared_from_this<B>
, то это разные базовые классы. - person Simple   schedule 02.12.2015shared_from_this
? Вы должны указать. Я не утверждаю, что какие-либо из этих трудностей непреодолимы, они просто усложняют код, которого не было бы, если бы неenable_shared_from_this
наследования. - person Jonathan Mee   schedule 02.12.2015shared_from_this()
, теперь они должны знать, вызывать лиA::shared_from_this()
илиB::shared_from_this()
, эта трудность усугубляется, если возвращаетсяshared_ptr
. Как я могу внутренне узнать, какой типshared_ptr
вызывающему абоненту нуженshared_ptr<A>
илиshared_ptr<B>
? Опять же, не непреодолимым, это просто добавляет сложности. - person Jonathan Mee   schedule 02.12.2015enable_shared_from_this
или ваша иерархия классов должна быть изменена, чтобы иметь один базовый класс, который обеспечивает функциональностьshared_from_this
. - person Jonathan Wakely   schedule 02.12.2015shared_ptr
иenable_shared_from_this
, чтобы понять, почему они такие, какие есть. Вы должны иметь возможность построитьshared_ptr<T>
из уже существующегоT
; наличиеenable_shared_from_this<T>
в качестве базового класса означает, что конструкторshared_ptr<T>
может хранитьweak_ptr<T>
внутриT
. - person Simple   schedule 02.12.2015*this
. Оно не может. 3. Если вы видите камень преткновения, укажите, где именно он находится. - person n. 1.8e9-where's-my-share m.   schedule 02.12.2015enable_shared_from_this
предназначен для получения, и общие опасения по поводу наследования не должны быть фактором при принятии решения о том, использовать ли его так, как он предназначен для использования. - person Pete Becker   schedule 02.12.2015