【问题标题】:c++ virtual Diamond inheritance [duplicate]c ++虚拟钻石继承[重复]
【发布时间】:2013-10-01 09:21:16
【问题描述】:

假设我们得到了一个菱形继承,其中 D 继承自 B1 和 B2,其基数为 V,如下所示:

struct V { 
    V(){cout << "V()" << endl;}
    V(int){cout << "V(int)" << endl;}
}; 
struct B1 : virtual V {
    B1(){cout << "B1()" << endl;}
    B1(int i): V(i) {cout << "B1(int)" << endl;
        /*…*/ }
};
struct B2 : virtual V {
    B2(){cout << "B2()" << endl;}
    B2(int i) { cout << "B2()" << endl; }
};
struct D : B1, B2 {
    D(int i): V(i) { cout << "D(int)" << endl; }
};

当我初始化 D* 参数时,我希望 B1 和 B2 默认构造函数调用 V 构造函数。但是,当我运行下一行时, V 被调用了一次。为什么?

D* d = new D(1);

提前致谢。

【问题讨论】:

  • 简而言之:虚拟基类由最派生类的构造函数初始化。
  • 这正是虚拟继承的用途。如果您确实想要两个不同的V 子对象,请不要使用虚拟继承。

标签: c++ inheritance diamond-problem


【解决方案1】:

虚拟基类的构造函数总是只调用一次,从最派生的类开始;这就是它的工作原理。多次建造基地是没有意义的。

尝试向基本构造函数添加一个参数,看看会发生什么。

【讨论】:

  • 继承是不是说派生类负责构建所有的基类?
  • @HeshamYassin 否。最派生类负责构造所有虚拟基类及其直接基类。
【解决方案2】:

基类V被调用一次,因为V1V2从V继承了virtualy。如果你不能继承virtualy,就会出现问题:例如,如果我调用基类的方法从派生的编译器无法知道哪个基类调用,一个是从V1 构造的,另一个是从V2 构造的。

所以虚拟继承让我们有可能在没有这个问题的情况下拥有钻石继承性。

【讨论】:

    猜你喜欢
    • 2012-11-05
    • 2020-01-01
    • 2017-12-09
    • 2012-04-19
    • 2016-09-21
    • 2011-02-09
    • 1970-01-01
    相关资源
    最近更新 更多