是跳过的非具体类的虚类的基构造函数

Are the base constructors of virtual class from non concrete classes skipped?

本文关键字:构造函数      更新时间:2023-10-16

我有这样的代码:

class Base{
public:
  int x;
  Base(int x){
    this->x = x;
  }
  virtual ~Base(){
    cout<<"base destroyed"<<endl;
  }
};
class A: public virtual Base{
public:
  A(int x) : Base(x){   //is this base call here skipped?
  }
  virtual ~A(){
    cout<<"a has been destroyed"<<endl;
  }
};
class B: public A{
public:
  B():Base(10),A(12){      //initialized from here, overwrite attempt
  }
};
int main(int argc, char** argv) {
  B ey;
  cout<<ey.x<<endl;
  return 0;
}

我尝试在具体类的构造函数初始化时覆盖它:

B():Base(10),A(12){ 

输出仍然是10.

既然类A不是我的具体类,它是否跳过了基类的构造函数?

A(int x):Base(x){

虚基类仅由最派生类的构造函数构造,在本例中为B。(它们恰好是在构造派生类的任何非虚直接基类之前先构造的。)

因为在你的例子中A不是最派生的类,它的构造函数不构造虚基。

之所以会发生这种情况,是因为基类构造函数只会被调用一次。它不会被调用多次。首先,为对象分配内存,然后调用Base的构造函数,然后调用A的构造函数,最后调用B的构造函数。基本上,在为对象分配内存之后,遍历从根类开始的继承树,并执行特定于每个派生部分的构造。层次结构中每个类的构造函数将只被调用一次。因此,只有当我们在A的构造函数中再次修改x的值时,那么只有x的值在对象中发生了变化。