为什么抽象派生类需要初始化虚拟基类?

Col*_*nee 5 c++ inheritance virtual-inheritance

请参见以下代码:

struct Object;

struct Component
{
    Component(Object* obj) { }
};

struct Renderable : public virtual Component
{
    virtual void Render() = 0;
};

struct AnimationRenderer : public Renderable
{
    AnimationRenderer(Object* obj) : Component(obj) { }
    virtual void Render() { }
};
Run Code Online (Sandbox Code Playgroud)

由于没有与Component::Component()from的匹配调用,因此无法编译Renderable::Renderable()

我可以通过提供Renderable一个构造函数来使此示例工作Renderable() : Component(NULL) { }即使Renderable将永远无法初始化Component

因为Renderable是抽象类,所以永远不能直接实例化它。由于它实际上是从继承的Component,因此它将永远无法调用的初始化Component

语言要求永远/永远不能调用代码的原因是什么?

Ben*_*igt 3

事实上,语言并不需要这样。您的编译器未使用当前的 C++ 规则。

\n\n

12.6.2p8 说(我的黑体字是为了强调):

\n\n
\n

[ 注意:抽象类永远不是最派生类,因此它的构造函数永远不会初始化虚拟基类,因此可以省略相应的内存初始化器。\xe2\x80\x94 尾注]

\n
\n\n

我在 C++03 中找不到该规则,因此这是 C++ 中公认的缺陷,现已修复。查找支持 C++11 的编译器更新。

\n\n

我能找到的 C++03 中最接近的相关规则在第 12.6.2p6 节中:

\n\n
\n

在执行任何非最派生类的类的构造函数期间,应忽略命名虚拟基类的内存初始化程序

\n
\n