Подтвердить что ты не робот

Есть ли недостаток в том, чтобы сделать наследование ALL виртуальным?

Я занимаюсь разработкой структуры для нашего внутреннего использования и мысли, что все виртуальные наследования позволят избежать проблемы с алмазом для других разработчиков, унаследовавших мои классы.

Я огляделся и нашел много дискуссий об использовании виртуального наследования, КОГДА столкнулся с проблемой алмаза, но ничего не выгнал.

4b9b3361

Ответ 1

То, что я нашел в стандарте:

  • Виртуальный базовый класс инициализируется самым производным типом (см. aschepler).
  • Вы не можете использовать static_cast для преобразования в ссылку/указатель производного класса, если это связано с виртуальным наследованием. [expr.static.cast]/2, 11
  • Вы не можете использовать C-style casts ( "Явное преобразование типа (отличная нотация)" ), чтобы преобразовать в указатель/ссылку производного класса ([expr.cast]), по крайней мере, пример в [expr.dynamic. cast]/9 говорит так. (oooh нет стилей в стиле C);
  • Копирование/перемещение назначения и ctor не могут быть тривиальными, если существует виртуальный базовый класс. [class.copy]/12, 25
  • [class.copy]/28 "Неизвестно, назначаются ли подобъекты, представляющие виртуальные базовые классы более одного раза, с помощью неявно заданного оператора присваивания копии".
  • У вас не может быть constexpr ctors, если есть виртуальный базовый класс. [Dcl.constexpr]/4
  • Существуют другие тонкости, такие как преобразования указателя на член [conv.mem]/2 и повторное использование хранилища с помощью размещения-new на this [basic.life]/5,6.

В зависимости от реализации виртуальных базовых классов могут быть и другие недостатки.

Ответ 2

Помните, что при не виртуальном наследовании каждый конструктор вызывает конструкторы сразу же базовых классов. Но с виртуальным наследованием наиболее производный класс должен вызывать конструкторы всех виртуальных базовых классов.

Если ваши базовые классы нуждаются в инициализации, виртуальное наследование будет означать, что каждый класс с дерева должен будет правильно инициализировать его. И любой класс в середине дерева не может рассчитывать на то, что его собственный базовый класс инициализируется так, как хотелось бы.