16

我正在开发一个供我们内部使用的框架,并认为使所有继承虚拟化可以避免其他开发人员从我的类继承的钻石问题。

我环顾四周,发现很多关于在遇到钻石问题时使用虚拟继承的讨论,但没有关于抢占它的讨论。

4

2 回答 2

13

请记住,对于非虚拟继承,每个构造函数都只调用直接基类的构造函数。但是对于虚拟继承,最派生的类需要调用所有虚拟基类的构造函数。

如果您的基类需要初始化,虚拟继承将意味着树下的每个类都需要正确初始化它。而且树中间的任何类都不能指望它自己的基类按照它想要的方式进行初始化。

于 2013-06-09T18:06:37.787 回答
6

正是我在标准中发现的:

  • 虚拟基类由派生最多的类型初始化(参见aschepler的回答)。
  • static_cast如果涉及虚拟继承,则不能使用 a转换为派生类引用/指针。[expr.static.cast]/2, 11
  • 您不能使用 C 样式转换(“显式类型转换(转换表示法)”)转换为派生类指针/引用([expr.cast]),至少在 [expr.dynamic.cast]/ 中的示例9 这么说。(哦,没有 C 风格的演员表;)
  • 如果有一个虚拟基类,复制/移动分配和 ctor 就不会是微不足道的。[class.copy]/12, 25
  • [class.copy]/28 “未指定表示虚拟基类的子对象是否由隐式定义的复制分配运算符多次分配。”
  • 如果有一个虚拟基类,你就不能有 constexpr ctors。[dcl.constexpr]/4
  • 还有其他一些微妙之处,例如指向成员的转换 [conv.mem]/2,以及通过this[basic.life]/5,6 上的placement-new 重用存储。

根据虚拟基类的实现,可能还有其他缺点。

于 2013-06-09T18:23:09.220 回答