Двойное наследование enable shared от этого



У меня есть объект (Z), производный от двух других объектов (A и B).



A и B оба являются производными от enable_shared_from_this<>, соответственно enable_shared_from_this<A> и enable_shared_from_this<B>.



Конечно, я вызываю shared_from_this() на Z. И, конечно, компилятор сообщает об этом как о неоднозначном.



Мои вопросы таковы:




  • безопасно ли наследовать дважды от enable_shared_from_this<> или это создаст два разделенных отсчета ссылок (плохо !)

  • если не безопасно, как я могу решить эту проблему ?


Примечание :
Я нашел этот другой вопрос плохой слабый указатель, когда базовый и производный классы наследуют от boost:: enable_shared_from_this , но на самом деле он не отвечает. Должен ли я тоже использовать трюк virtual?

533   2  

2 ответов:

Да, согласно плохой слабый указатель, когда базовый и производный класс оба наследуют от boost::enable_shared_from_this решение заключается в использовании виртуального наследования. Вот реализация для стандарта C++11 shared_ptr (не Boost):

#include <memory>

struct virtual_enable_shared_from_this_base:
   std::enable_shared_from_this<virtual_enable_shared_from_this_base> {
   virtual ~virtual_enable_shared_from_this_base() {}
};
template<typename T>
struct virtual_enable_shared_from_this:
virtual virtual_enable_shared_from_this_base {
   std::shared_ptr<T> shared_from_this() {
      return std::dynamic_pointer_cast<T>(
         virtual_enable_shared_from_this_base::shared_from_this());
   }
};

struct A: virtual_enable_shared_from_this<A> {};
struct B: virtual_enable_shared_from_this<B> {};
struct Z: A, B { };
int main() {
   std::shared_ptr<Z> z = std::make_shared<Z>();
   std::shared_ptr<B> b = z->B::shared_from_this();
}

Это не является частью реализации по умолчанию, вероятно, из-за накладных расходов виртуального наследования.

Да, ваш класс будет производным от двух различных классов enable_shared_from_this<A> и enable_shared_from_this<B>, и иметь два разных слабых ref

Трюк из этого ответа позволяет иметь один базовый класс, из-за виртуального наследования

Comments

    Ничего не найдено.