C++派生类的构造函数和析构函数
如果对此不做说明,则编译器认为基类对象要用无参构造函数初始化 如果基类没有无参构造函数,则会导致编译错误。
在执行一个派生类的构造函数之前,总是先执行基类的构造函数。
和封闭类说明成员对象如何初始化类似,派生类说明基类对象如何初始化,也需要在构造函数后面添加初始化列表。在初始化列表中,要指明调用基类构造函数的形式。具体写法如下:
构造函数名(形参表): 基类名(基类构造函数实参表)
{
}
派生类对象消亡时,先执行派生类的析构函数,再执行基类的析构函数。
下面的程序演示了派生类的构造函数和析构函数的调用顺序:
#include iostream #include string using namespace std; class CBug { int legNum, color; public: CBug(int ln, int c1) : legNum(ln), color(c1) cout CBug Constructor endl; ~CBug() cout CBug Destructor endl; void Printlnfo() cout legNum , color endl; class CFlyingBug : public CBug int wingNum; public: //CFlyingBug(){} 若不注释掉则会编译出错 CFlyingBug::CFlyingBug(int ln, int c1, int wn) : CBug(ln, c1), wingNum(wn) cout CFlyingBug Constructor endl; ~CFlyingBug() cout CFlyingBug Destructor endl; int main() { CFlyingBug fb(2, 3, 4); fb.Printlnfo(); return 0; }
程序输出结果:
CBug Constructor
CFlyingBug Constructor
2,3
CFlyingBug Destructor
CBug Destructor
第 25 行如果没有注释掉会编译出错。因为这个构造函数没有说明在派生类对象用该构造函数初始化的情况下,其基类对象该如何初始化 这也就意味着基类对象应该用无参构造函数初始化,可是 CBug 类并没有无参构造函数,所以编译会出错。
第 26 行中的 CBUg(ln, c1) 指明了在派生类对象用该构造函数初始化的情况下,其基类对象的初始化方式。
思考题:派生类对象生成时要先执行基类构造函数,消亡时要先执行自身析构函数,再执行基类析构函数,为什么?
和封闭类的情况类似,如果一个派生类对象是用默认复制构造函数初始化的,那么它内部包含的基类对象也要用基类的复制构造函数初始化。
多层次的派生在 C++ 中,派生可以是多层次的。例如学生类派生出中学生类,中学生类又派生出初中生类和高中生类。总之,类 A 派生类 B,类 B 可再派生类 C,类 C 又能派生类 D,以此类推。
这种情况下,称类 A 是类 B 的直接基类,类 B 是类 C 的直接基类,类 A 是类 C 的间接基类。当然,类 A 也是类 D 的间接基类。在定义派生类时,只写直接基类,不写间接基类。派生类沿着类的层次自动向上继承它所有的间接基类。
派生类的成员包括派生类自己定义的成员、直接基类中定义的成员,以及所有间接基类的全部成员。
当派生类的对象生成时,会从最顶层的基类开始逐层往下执行所有基类的构造函数,最后再执行自身的构造函数;当派生类对象消亡时,会先执行自身的析构函数,然后从底向上依次执行各个基类的析构函数。
例如下面的程序:
#include iostream using namespace std; class A { public: int n; A(int i) :n(i) { cout A n constructed endl; } ~A() { cout A n destructed endl; } class B :public A public: B(int i) :A(i) { cout B constructed endl; } ~B() { cout B destructed endl; } class C :public B { public: C() :B(2) { cout B constructed endl; } ~C() { cout B destructed endl; } int main() C Obj; return 0; }
程序的输出结果:
A 2 constructed
B constructed
B constructed
B destructed
B destructed
A 2 destructed
在派生类也是封闭类的情况下,构造函数的初始化列表不但要指明基类对象的初始化方式,还要指明成员对象的初始化方式。
派生类对象生成时,会引发一系列构造函数调用,顺序是:先从上至下执行所有基类的构造函数,再按照成员对象的定义顺序执行各个成员对象的构造函数,最后执行自身的构造函数;而派生类对象消亡时,先执行自身的析构函数,然后按与构造的次序相反的顺序依次执行所有成员对象的析构函数,最后再从底向上依次执行各个基类的析构函数。
21553.html
chtml相关文章
- C++中转换构造函数与默认函数的优先级
- C++ 类构造函数&解析函数
- 【语言-C++】多线程通同步 临界区 CCriticalSection 与 CSingleLock
- 深入理解C++11_c++ string char
- C++基础入门_C语言入门基础
- C++ 不知图系列之基于邻接矩阵实现广度、深度搜索
- windows编程入门-六星云课堂:零基础学C/C++编程?看看下面这几个步骤
- C/C++ 反汇编:针对加减乘除的还原
- C++:二叉搜索树
- C++ 测试框架 GoogleTest 初学者入门篇 乙
- 【C++】通过priority_queue、reverse_iterator加深对于适配器和仿函数的理解
- c++面向对象设计(谭浩强)2.3类的成员函数
- C++ deque添加和删除元素方法详解
- C++梅森旋转算法生成随机数(mersenne_twister_engine)详解
- C++重载插入运算符(<<)和提取运算符(>>)详解
- C++ peek函数用法详解
- C++函数模板声明和实现
- 从汇编看c++函数的默认参数的使用说明
- 深入探讨C++父类子类中虚函数的应用
- C/C++回调函数介绍
- C++循环队列实现模型