您的位置:首页 > 编程语言 > C语言/C++

C++ 派生类构造函数、析构函数调用 [大三TJB_708]

2013-01-28 15:42 246 查看

《C++面向对象程序设计》第二版 杜茂康 李昌兵

1 派生类构造函数、析构函数描述

作用和形式

派生类可能有多个基类,也可能包括多个对象成员(指本类中的数据成员,此数据成员为某类定义的对象)。在创建派生类对象时,派生类的构造函数除了要负责本类成员的初始化外,还要调用基类和对象成员的构造函数,并向它们传递参数,以完成基类子对象和对象成员的建立和初始化
派生类只能采用构造函数初始化列表的方向(顺序)【其实类申明和对象申明先决定构造函数的调用顺序】向基类或对象成员的构造函数传递参数,形式如下:
派生类构造函数名(参数表):基类构造函数名(参数表),对象成员1(参数列表),...{
......
}
派生类在构造函数初始化列表(在派生类构造函数中调用基类构造函数和对象成员并传递参数的语句,就是派生类函数名(参数表):后面的语句列表,把这些语句看成列表)中为基类和对象成员的构造函数初值。当用派生类定义对象时,程序首先调用基类构造函数;接下来构造对象成员(1),最后调用派生类的构造函数。

2 派生类构造函数必需与否

在基类没有任何构造函数或者基类具有缺省参数的构造函数时,派生类可以不向基类传递参数甚至不需要构造函数(本类没有需要初始化的数据成员),由C++系统隐士生成派生类和基类的构造函数并隐士调用;当基类或对象成员所属类只含有带参数的构造函数时,即使派生类本身没有需要初始化的数据也必须定义构造函数对基类或对象的构造函数传递参数。


3 派生类的构造函数只负责直接基类的初始化

C++标准有一跳规则:如果派生类的基类同时也是另外一个类的派生类,则每个派生类只负责它的直接基类的构造函数调用。
举例,有A,B,C三个类,它们都有构造函数这个成员函数。其关系如图1



图1.类派生类后又派生类
当由类C定义对象时,构造函数调用的次序为:C的基类B的构造函数被调用;在调用B的构造函数时,由于B又是由类A派生的,所以先调用A的构造函数;然后回溯到A的派生类B,最后回溯到B的派生类C。B和C的构造函数是在回溯中被调用的。

4 构造函数的调用时间和次序

当派生类具有多个基类和多个成员对象时,它们的构造函数将在创建派生类对象时被调用,调用次序如下:
基类构造函数-->对象成员构造函数-->派生类构造函数

当有多个基类时,将按照它们继承方式中的声明次序调用。
当有多个对象成员时,将按它们在派生类中的声明次序调用。
当构造函数初始化列表的基类和对象成员的构造函数调用完成之后,才执行派生类构造函数体中的代码。
如果某个对象成员没有在派生类构造函数的初始化列表中,则编译器会自动为其对象构造(对应类为缺省参数即无参数),调用对应构造函数的顺序跟对象被申明的对象相同。



5 构造函数调用次序例子

[code]#include <iostream>

class A {
	int x;
public:
	A (int i=0) {
		x=i;
		cout <<"A------"<<x<<end1;
	}
};

class B {
	int y;
public:
	B(int i){
		y = i;
		cout <<"B----------"<<y<<end1;
	}
};

class C : public B {
public:
	A a0, a1;
	C():a1(2),  B(1){
		cout << "C-----------3"<<end1;
	}
};

void main()
{
	C c;
}


在main函数中,当派生类C定义对象c时,将按照B->a0->a1->c的次序调用其内的构造函数。尽管C类的构造函数的参数列表方向为a0(A类缺省参数,编译器按照此顺序自动调用a0对象的构造函数)a1,B1,但是对构造函数的调用次序起决定作用的还是申明次序和类继承关系。所以此程序的执行结果如下:
B----------1
A------0 //编译器自动调用a0的构造函数构造对象a0
A------4
C-----------3

这次的笔记将会为理解MFC程序执行流程带去铺垫。



此次笔记记录完毕。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: