C++ 抽象类的虚拟基类初始化

C++ 抽象类的虚拟基类初始化,c++,constructor,abstract-class,C++,Constructor,Abstract Class,以代码为例: #include <iostream> using std::cout; using std::endl; struct A { virtual void foo(){ }; A() { cout << "A()" << endl; } }; struct B : virtual A { virtual void bar() = 0; B() : A() //mem-ini

以代码为例:

#include <iostream>

using std::cout;
using std::endl;

struct A
{
    virtual void foo(){ };

    A()
    {
        cout << "A()" << endl;
    }
};

struct B : virtual A
{
    virtual void bar() = 0;

    B() : A() //mem-initializer of virtual base class
    {
        cout << "B()" << endl;
    }
};

struct C : B
{
    void bar(){ };
    C() : B()
    {
        cout << "C()" << endl;
    }
};

C c;

int main()
{
    //A()
    //B()
    //C()
    //Is output
}
#包括
使用std::cout;
使用std::endl;
结构A
{
虚拟void foo(){};
()
{

cout它是在谈论这样的事情:

#include <iostream>

using std::cout;
using std::endl;

struct A
{
    virtual void foo(){ };

    // N.B.: no default ctor
    A(int)
    {
        cout << "A(int)" << endl;
    }
};

struct B : virtual A
{
    virtual void bar() = 0;

    B()
    {
        cout << "B()" << endl;
    }
};

struct C : B
{
    void bar(){ };
    C() : A(10), B()
    {
        cout << "C()" << endl;
    }
};

C c;

int main()
{

}
#包括
使用std::cout;
使用std::endl;
结构A
{
虚拟void foo(){};
//注意:无默认值
A(整数)
{

cout如果
B
非虚拟地继承自
A
,则
B
的构造函数必须初始化
A
基类子对象。由于
A
有一个默认构造函数,您不必在
B
的构造函数初始值设定项中明确提及
A
。但是,如果
A
没有de>的话错误构造函数和非虚拟继承自
A
B
必须在
B
的ctor初始值设定项中显式初始化
A


如果
B
实际上继承自
A
,并且
B
是一个抽象类,那么即使
A
没有默认构造函数,您仍然不需要在
B
的ctor初始值设定项中提及
A
。这是因为
B
的构造函数永远不会负责初始化
A
子对象;相反,派生最多的类的构造函数是必须初始化
A
子对象的构造函数,因为
A
是一个虚拟基类。

您的示例没有太多说明,因为虚拟基
A
有一个默认构造函数。您永远不必显式调用默认构造函数对于一个虚拟基类(或任何与此相关的基类),编译器将在任何需要的地方隐式调用该默认构造函数,而不管您是否自己显式地调用它

删除默认构造函数,并在
a

struct A
{
    A(int)
    {
        cout << "A()" << endl;
    }
};
因为C不是一个抽象类

但是您不必从
B
的构造函数初始化
A
,因为
B
是一个抽象类

struct B : virtual A
{
    virtual void bar() = 0;

    B()
    {
        cout << "B()" << endl;
    }
};
结构B:虚拟A { 虚拟空心条()=0; B() {
难道我仍然看不到§12.6.2/8(C++11)中的注释的相关性。例如,为
a
声明一个默认构造函数(您不需要定义它)就足够了,以便在GCC中编译代码。我想这个问题与
B::B()中缺少
a
的mem初始值无关
,但编译器在解析
B
时没有找到
a
的默认构造函数。如果您只在
a
中包含此声明,问题就解决了。@Belloc关键是该声明不是标准所要求的。GCC要求它的事实是一个bug。但这不是问题257抱怨:
抽象基类的构造函数必须为直接或间接派生它的每个虚拟基类提供mem初始值设定项吗?因为虚拟基类的初始化是由派生最多的类执行的,而且抽象基类永远不可能是派生最多的类,所以似乎没有理由要求抽象基类的构造函数初始化虚拟基类。
我错了。请参阅此讨论,并参阅我对@T.C的评论。above@Belloc很抱歉,我不太理解你的问题。请参阅此讨论
struct B : virtual A
{
    virtual void bar() = 0;

    B()
    {
        cout << "B()" << endl;
    }
};