1、虚基类的构造函数;虚基类构造函数如果有多个,虚基类则构造函数的调用顺序是某类在类派生表中出现的顺序而不是它们在成员初始化表中的顺序;
2、如果派生类中的基类有虚基类的话,而且该派生类不止有一个基类,那么优先调用虚基类的构造函数,先按照派生列表的顺序调用虚基类的构造函数,等虚基类的构造函数全部调用完,再按照派生列表的顺序调用非虚基类的构造函数
3、创建派生类的对象,基类的构造函数函数优先被调用(也优先于派生类里的成员类);基类如果有多个,则构造函数的调用顺序是某类在类派生表中出现的顺序而不是它们在成员初始化表中的顺序;
4、如果类里面有成员类,成员类的构造函数优先被调用;成员类对象构造函数如果有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序而不是它们出现在成员初始化表中的顺序;
5、从虚基类直接或间接派生的派生类中的构造函数的成员初始化列表中都要列出对虚基类构造函数的调用。但仅仅用建立对象的最远派生类的构造函数调用虚基类的构造函数,而该派生类的所有基类中列出的对虚基类的构造函数的调用在执行中被忽略,从而保证对虚基类子对象只初始化一次。。
6、派生类构造函数
作为一般规则派生类构造函数应该不能直接向一个基类数据成员赋值而是把值传递 给适当的基类构造函数否则两个类的实现变成紧耦合的(tightly coupled)将更加难于正确地修改或扩展基类的实现。(基类设计者的责任是提供一组适当的基类构造函数)
实例1:
class F : virtual public A, public D ,virtual public C,public B
{
public:
F():C(),A(),B(),D() //其中,虚基类 A,C必须在初始化列表中(第5条)
{
....
}
};
当产生F类对象,构造函数调用顺序:
1)调用 A类构造函数,在调用C类构造函数 (第2条,先调虚基类,第1条,顺序为派生表中顺序,而非初始化列表中的顺序)
2)调用 D类构造函数,在调用B类构造函数(第2条,再调虚基类,第1条,顺序为派生表中顺序,而非初始化列表中的顺序)
class A
{
public:
A();
}
class B
{
public:
B();
}
class F : public D ,virtual public C
{
public:
F():C(),D()
{
....
}
public:
A a;
B b;
};
当产生F类对象,构造函数调用顺序:
1)先调用C类构造函数,再调用D类构造函数
(第3条,基类构造函数 先于 成员变量构造函数)
2)然后调用A类构造函数、B类构造函数(变量a
先于 b申明)
3)最后调用F类的构造函数。(成员类构造函数先于本类,所以F类最后调用)