LINUX.ORG.RU

shared_from_this

 ,


0

2

допустим есть такие классы

class A : public enable_shared_from_this<A>
{
public:
//some methods
};

class B : public A, public enable_shared_from_this<B>
{
public:
//some methods
};

вопрос вот в чем.. как поведет себя shared_from_this в методах класса B?

при таком множественном наследовании ты пытаешься запихнуть контракт из шаблонного класса enable_shared_from_this в класс B дважды. оно ваще конпелицо?

x0r ★★★★★ ()
Последнее исправление: x0r (всего исправлений: 1)
Ответ на: комментарий от x0r

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

pozitiffcat ★★★ ()

Очевидно будет ругаться на ambiguous методы и поля, смотря как написать класс, который работает в связке с enable_shared_from_this. Вообще логика подсказывает, что так делать не нужно. Догадываюсь, что шаблонный параметр нужен, чтобы вызвать правильный деструктор, ибо он невиртуальный. Тогда удаление через enable_shared_from_this<A> пропустит деструктор B, а enable_shared_from_this<B> проигнорирует счётчик ссылкок в A. Вобщем, каша.

Dendy ★★★★★ ()

Enable_shared_from_this содержит weak_ptr, из которого создаются все shared_ptr. Здесь в B будут два таких weak_ptr и для B будут создаваться разные shared_ptr при использовании A::shared_from_this() и B::shared_from_this(), из-за чего может быть двойное удаление.

gv ()

У меня как-то возникало подобное желание. Не помню точно, вроде, так даже не скомпилится (а если вдруг и скомпилится, то легче не будет). После размышлений о смысле жизни я пришёл к следующим выводам:

  • наследовать enable_shared_from_this должен «финальный» класс или, на худой конец, последний в цепочке наследования, которому нужен shared_from_this();
  • надо избегать ситуации, когда в базовом классе нужен shared_from_this(), а если всё-таки настигло, то можно использовать костыли, например:
    • переделать нехорошие методы базового класса в статические, принимающие shared_ptr на себя;
    • сделать в базовом классе метод
      private: virtual shared_ptr<Base> selfBase() = 0;
      и, по вкусу, ещё один такой же с const.

С нетерпением жду более красивого решения от ниже отписавшихся.

const86 ★★★★★ ()
Последнее исправление: const86 (всего исправлений: 1)
Ответ на: комментарий от gv

Почему нельзя сделать например так?

С ходу проблем не вижу. Кроме моей личной неприязни к static_cast от базового к дочернему, но тут безопасно. Хоть и тоже костыль, но не такой жуткий.

const86 ★★★★★ ()
Ответ на: комментарий от const86

последний в цепочке наследования, которому нужен shared_from_this();

спасибо пока так и сделал, остальные проблемы решил фабриками

pozitiffcat ★★★ ()
Ответ на: комментарий от gv

Почему нельзя сделать например так?

Вспомнил: при виртуальном наследовании static_cast не взлетит, нужен dynamic_cast.

const86 ★★★★★ ()
Ответ на: комментарий от const86

Вспомнил: при виртуальном наследовании static_cast не взлетит, нужен dynamic_cast.

Точно, спасибо.

gv ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.