多继承对象初始化顺序:
(a) 基类初始化
(b) 对象成员初时化
(c) 构造函数的赋值语句
l (a) 基类初始化——
构造函数初始化式只能控制用于初始化基类的值,不能控制基类的构造顺序。基类构造函数按照基类构造函数在类派生列表中出现的次序调用。——《C++ Primer》
class C: public B2, public B1, public B3
{
public: //派生类的公有成员
C(int a, int b, int c, int d)
: B1(a), B2(b) ,memberB2(d),memberB1(c)
{
}
private: //派生类的私有对象成员
B1 memberB1;
B2 memberB2;
B3 memberB3;
};
上例中,在类派生列表中出现的次序即为public B2, public B1, public B3
所以最先初始化的分别是B2,B1,B3,那么哪些需要被初始化呢?
因为 ,所以基类需要被初始化的是B1(a), B2(b) (注意,memberB2(d),memberB1(c)是其对象成员,不能在这里初始化),但是没有出现B3,不过没有关系,实验表明上式等价于C(int a, int b, int c, int d) : B1(a), B2(b) ,B3(), memberB2(d),memberB1(c)形式,至于为什么呢?我自己的理解是,B3无参数,所以可以省去。
所以调用B1 B2 B3的构造函数,输出
constructing B2 2
constructing B1 1
constructing B3 *
l (b) 对象成员初时化——
所谓对象成员是指 ,按照对象成员的顺序初始化,即输出
constructing B1 3
constructing B2 4
constructing B3 *
如果将顺序变化一下:
private: //派生类的私有对象成员
B1 memberB1;
B3 memberB3;
B2 memberB2;
};
输出顺序随之改变——
constructing B1 3
constructing B3 *
constructing B2 4
至此,已经输出:
constructing B2 2
constructing B1 1
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *
与实际运行效果相符,但是我们增加点难度,再来看一下
l (c) 构造函数的赋值语句
class C: public B2, public B1, public B3
{
public: //派生类的公有成员
C(int a, int b, int c, int d)
: B1(a), B2(b) ,memberB2(d),memberB1(c)
{
cout<<"abcdefg/n";
}
private: //派生类的私有对象成员
B1 memberB1;
B2 memberB2;
B3 memberB3;
};
实际输出结果——
constructing B2 2
constructing B1 1
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *
abcdefg
可见,构造函数的赋值语句(比如在cout<<"abcdefg/n";处加入int i = 0;这就是构造函数的赋值语句)是最后执行的。