构造函数
● 基类的构造函数和析构函数不能被派生类所继承, 对于派生类的构造函数和析构函数应注意的有:
如果基类中没有构造函数,派生类也可以不定义构造函数(也可以定义),都使用默认的构造函数。 派生类中的新增数据成员可以使用其它公有成员函数来设置初始值。
如果在基类中定义了缺省构造函数(没有参数的构造函数 和 带有默认值参数的构造函数 都称为 缺省构造函数) 或者 根本没有定义任何一个构造函数( 此时, 由编译器自动生成的缺省构造函数)时, 在派生类中的构造函数的定义中可以省略对基类构造函数的调用。 即省略 基类名(参数表)。
如果基类定义了带有形参表的构造函数, 那么派生类就必须定义新的构造函数,提供一个将参数传递给基类构造函数的途径, 保证在基类进行初始化时能够得到必要的数据。 因此, 如果基类中定义了一个或多个参数时, 派生类就必须定义构造函数。
对派生类对象的清理工作也需要加入新的析构函数。
对象成员的情况与基类相同。
对基类成员和子对象成员的初始化必须在派生类的构造函数中的初始化列表中进行, 派生类的数据成员既可以在初始化列表中初始化也可以在该构造函数的函数体初始化。
派生类构造函数必须对 基类成员、(如果有)成员对象、派生类自己的数据成员初始化, 其执行顺序是首先调用基类的构造函数,然后成员对象的构造函数, 最后调用派生类的构造函数体。
● 当派生类有多个基类时, 处于同一层次的各个基类的构造函数的调用顺序取决于定义派生类时声明的顺序(自左向右), 而在派生类构造函数的成员初始化列表中给出的顺序无关。
当派生类有多个成员对象时, 各个成员对象的构造函数的调用顺序取决于在派生类中定义的顺序(自前向后),而在派生类构造函数的成员初始化列表中给出的顺序无关。
如果派生类的基类也是一个派生类,则每个派生类只需要负责其直接基类的构造,依次上溯。 而当所有的基类和成员对象的构造函数都可以省略时, 可以省略派生类构造函数的成员初始化列表。
析构函数
● 派生类析构函数的执行顺序与构造函数相反。
下面看一个示例程序:
class base1
{
private:
int i;
public:
base1(int b)
{
i = b;
cout << "基类1的构造函数被调用" << " " << i << endl << endl;
}
virtual~base1()
{
cout << "基类1的析构函数被调用" << endl << endl;;
}
};
class base2
{
public:
base2(int j)
{
cout << "基类2的构造函数被调用" << " " << j << endl << endl;;
}
virtual~base2()
{
cout << "基类2的析构函数被调用" << endl << endl;;
}
};
class base3
{
public:
base3()
{
cout << "基类3的构造函数被调用" << endl << endl;;
}
virtual~base3()
{
cout << "基类3的析构函数被调用" << endl << endl;;
}
};
class derive :public base2, public base1, public base3
{
private:
int ee;
base1 memberbase1;
base2 memberbase2;
base3 memberbase3;
public:
derive(int a, int b, int c, int d, int e) :base1(a), memberbase2(d), memberbase1(c), base2(b)
{
ee = e;
cout << "派生类的构造函数被调用" << " " << ee << endl << endl;;
}
virtual~derive()
{
cout << "派生类的析构函数被调用" << endl << endl;;
}
};
int main(int argc, char * argv[])
{
base1 *a = new derive(2, 4, 6, 8, 10);
delete a;
system("pause");
return 0;
}
输出结果为:
基类2的构造函数被调用 4
基类1的构造函数被调用 2
基类3的构造函数被调用
基类1的构造函数被调用 6
基类2的构造函数被调用 8
基类3的构造函数被调用
派生类的构造函数被调用 10
========================================================================================
派生类的析构函数被调用
基类3的析构函数被调用
基类2的析构函数被调用
基类1的析构函数被调用
基类3的析构函数被调用
基类1的析构函数被调用
基类2的析构函数被调用
请按任意键继续. . .