0

我很难解决这类问题。在几天后我要参加的考试中,他们展示了一个C++具有多重继承的程序:

struct X {
    X(){cout << "X" << endl;}
};

struct A : virtual X {
    int i;
    A(){cout << "A" << endl;}
};

struct B : A {
    int i;
    B(){cout << "B" << endl;}
    virtual void f() {cout << "f" << endl;}
};

struct C : A {
    int i;
    C(){cout << "C" << endl;}
    C(int i){cout << "C2" << endl;}
    virtual void g() {cout << "g" << endl;}
};

struct D : virtual B, virtual C {
    int i;
    D( int i) : C(i), B() {cout << "D" << endl;}
};

并显示来自 main 的一些代码:

D* d = new D(2014);
C* c = d;
B* b = d;

而不是问“输出会是什么?” 我不需要解决方案,我总是可以运行或调试它,但我需要理解直觉,因为我不会在考试中随身携带调试器。现在我知道了我需要遵循的算法:

5 初始化应按以下顺序进行:

— 首先,并且仅对于如下所述的最派生类的构造函数,虚拟基类应按照它们在基类的有向无环图的深度优先从左到右遍历中出现的顺序进行初始化,其中“从左到右”是派生类基说明符列表中基类名称的出现顺序。

— 然后,直接基类应按照它们出现在 base-specifier-list 中的声明顺序进行初始化(无论 mem-initializers 的顺序如何)。

— 然后,非静态数据成员应按照它们在类定义中声明的顺序进行初始化(同样不管 mem-initializers 的顺序)。

— 最后,构造函数的主体被执行。[注意:声明顺序是为了确保基子对象和成员子对象以初始化的相反顺序被销毁。]

但是我真的很难解决它们,这没有任何意义。是否有可能展示直觉,也许是解决这类问题的技巧或技巧?也许是为了显示黑暗的角落?也许以某种方式写下所有的类/结构,以某种方式编写 vbase 类以便于查看输出?

4

0 回答 0