C++中,构造基类是靠初始化列表么?

就是说,爷类,父类,子类。都是只有默认构造函数。创建子类对象。那么子类构造函数的初始化列表里自动生成父类构造函数(去调用)。调用父类构造函数时,父类的构造函数初始化列表里又有爷类构造函数

第1个回答  2013-08-07
是的,你都分析得那么清楚了。
子类构造函数必须对父类进行初始化,否则出错,父类有默认构造函数的时候可以不显式初始化。追问

如果我在类中都定义了一个无参数构造函数,那么创建时我不手动初始化列表,能顺利完成创建吗

追答

能,会自动调用默认构造函数(就是无参的那个)。

验证一下:

#include <iostream>
using namespace std;

class A{
public:
int x;
A(): x(5){}
};

class B: public A{
public:
int y;
B(): y(9){}
};

int main()
{
B b;
cout << b.x << endl;
return 0;
}

自动用5初始化了父类的x

追问

百科上说,从虚基类直接或间接派生的派生类中的构造函数的成员初始化列表中都要列出对虚基类构造函数的调用。 但仅仅用建立对象的最远派生类的构造函数调用虚基类的构造函数。 我不明白为何虚基类下面所有的派生类初始化列表中都有有他的构造函数??(虽然会被忽略) 一般来说,一个基类构造函数不是只在下一层初始化列表中的么

追答

这是因为虚基类,爷类只有一个,不能从任一父类中初始化(如果认为爷类是随父类带过去的,那么爷类就有两个了),所以子类要列出爷类的初始化列表。看例子:

#include <iostream>
#include <cstdlib>
using namespace std;

class A{
public:
A(){cout<<"A::A()"<<endl;}
};

class B1: virtual public A{
public:
B1(){cout<<"B1::B1()"<<endl;}
};

class B2: virtual public A{
public:
B2(){cout<<"B2::B2()"<<endl;}
};

class C: public B1, public B2{
public:
C(){cout<<"C::C()"<<endl;}
};

int main()
{
C c;
system("pause");
return 0;
}

例子中是C直接初始化了A, B1, B2。如果把virtual去掉,那么就变成了C初始化B1、B2,而B1、B2被初始化的时候各初始化了一遍A。

追问

我知道实现的原理,我就是不懂 从虚基类直接或间接派生的派生类中的构造函数的成员初始化列表中都要列出对虚基类构造函数的调用

其中,直接或者间接,都要。。。这些字眼我不懂。按常理来说,虚基类就是下一层的初始化列表中,跟底层的子类初始化列表中有。当然执行时前者被忽略,后者执行所以实现了。

但是语句上说,直接或者间接,都有其构造函数。这点我就不懂

追答

啊,我没想过这么深奥问题。测了一下:

#include <iostream>
#include <cstdlib>
using namespace std;

class A{
public:
A(int x){cout<<"A::A()"<<endl;}
};

class B1: virtual public A{
public:
B1():A(1){cout<<"B1::B1()"<<endl;}
};

class B2: virtual public A{
public:
B2():A(2){cout<<"B2::B2()"<<endl;}
};

class C1: public B1{
public:
C1():A(3){cout<<"C1::C1()"<<endl;}
};

class C2: public B1{
public:
C2():A(4){cout<<"C2::C2()"<<endl;}
};

class D: public C1, public C2{
public:
D():A(5){cout<<"D::D()"<<endl;}
};

int main()
{
D d;
system("pause");
return 0;
}

删掉任意一层的A类初始化列表都会出错。

第2个回答  2019-05-08
不能,你自己写的构造函数体,是在初始化列表执行之后才执行,也就是如果不写在列表里,就会调用默认构造函数构造基类对象部分。
相似回答