C++的类继承问题

来源:百度知道 编辑:UC知道 时间:2024/09/20 10:42:25
#include <iostream.h>
class b1
{
public:
b1(int i){cout<<"constructing b1"<<i<<endl;}
};

class b2
{
public:
b2(int j){cout<<"constructing b2"<<j<<endl;}
};

class b3
{
public:
b3(){cout<<"constructing b3*"<<endl;}
};
class c:public b2,public b1,public b3
{
public:
c(int a,int b,int c,int d):b1(a),memberb2(d),memberb1(c),b2(b)
{}
private:
b1 memberb1;
b2 memberb2;
b3 memberb3;
};
void main()
{
c obj(1,2,3,4);
}
输出结果是:
construcing b22
construcing b11
construcing b3*
construcing b13
construcing b24
construcing b3*
在基类中有缺省形式的构造函数,派生类中的构造函数的声明中可以省略,所以输出construcing b3*,但是最后还输出了construcing b3*这个是构造函数的,像memberb2(d),memberb1(c)都有写的,所以它会去调用构造函数,但是b3 memberb3;没有写为什么也会调用????
那也就是如果数据成员是类对象的话,一定会调用构造函数是不??
还有如果数据成

你要理解构造函数的过程,这道题你就明白了
构造函数实际上是分两个阶段的:
1,初始化阶段,就是你题目中的初始化列表。这里你写出来就是显式的调用初始化列表。在初始化列表中数据成员的初始化顺序与你列表中写的顺序无关,和声明顺序有关。由于你继承的时候,声明继承的顺序是b2,b1,b3.所以它会按照这个顺序调用相应的类的构造函数。这几个调用完后,才是自身类的数据成员,自身类的数据成员的初始化顺序也是和声明有关,和你初始化列表中写的顺序无关。你声明的顺序是
b1 memberb1;
b2 memberb2;
b3 memberb3;
所以后面才会出现
construcing b13
construcing b24
construcing b3*
,这里说的你显式使用了初始化列表,如果你没有使用,他照样会执行,只不过你没有指定构造函数的参数,所以它会调用数据成员的默认构造函数。因为你这里面没有显示说明b3这个基类,和memberb3这个数据成员,所以他们都会调用默认的构造函数,也就是
public:
b3(){cout<<"constructing b3*"<<endl;}
这上面说的就是初始化阶段,这个阶段是肯定先执行的,不管你自己写没有写初始化列表。没有写它会调用默认的。
2.计算阶段
也就是函数体{},他是在初始化阶段执行完之后,才执行的。
认识了这两个阶段,才进一步了解构造函数的过程。
不知道说清楚了没?
补充回答:
对如果是类数据成员的话,就会调用默认构造函数。
对于int,不会,因为它是内置类型,没有构造函数。

你的b3的构造函数是个重定义默认构造函数,而你定义:c obj(1,2,3,4);是编译器暗中调用了b3的默认构造函数(即你定义的那个)来初始化memberb3,所以会出现这个

private:
b1 memberb1;
b2 memberb2;
b3 memberb3;
这里只是作成员的声明
memberb3是成员变量,当类C构造时,m