C++学习之路—继承与派生(二):派生类的构造函数与析构函数
(根据《C++程序设计》(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明)
由于基类的构造函数和析构函数是不能被继承的,所以在声明派生类时,需要我们自己定义派生类的构造函数和析构函数。
1 派生类的构造函数
在设计派生类的构造函数时,不仅要考虑派生类所增加的数据成员的初始化,还要考虑基类的数据成员的初始化。也就是说,
希望在执行派生类的构造函数时,使派生类的数据成员和基类的数据成员同时都被初始化。解决这个问题的思路是:在执行派生类的构造函数时,调用基类的构造函数。
1.1 简单派生类的构造函数
简单的派生类只有一个基类,只有一级派生,且在派生类的数据成员中不包含基类的对象。通过具体的例子定义简单派生类的构造函数:
1: class Student //声明基类Student
2: {
3: public:
4: Student( int n , string nam , char s ) //定义基类的析构函数
5: {
6: num = n ;
7: name = nam ;
8: sex = s ;
9: }
10: ~Student(){} //基类的析构函数
11: protected:
12: int num ;
13: string name ;
14: char sex ;
15: };
16:
17: class Student1 : public Student //声明公用派生类Student1
18: {
19: public:
20: Student1( int n , string nam , char s , int a , string ad ) : Student( n , nam ,s )
21: //定义派生类的构造函数
22: //在函数体内只对派生类新增的数据成员初始化
23: {
24: age = a ;
25: addr = ad ;
26: }
27: ~Student1(){} //派生类的析构函数
28: private:
29: int age ;
30: string addr ;
31: };
请大家注意派生类构造函数首行的写法:
Student1( int n , string nam , char s , int a , string ad ) : Student( n , nam ,s )

Student1( int n , string nam , char s , int a , string ad ) ;
Student1 :: Student1 (int n , string nam , char s , int a , string ad ): Student( n, nam ,s )
{
age = a ;
addr = ad ;
}
1.2 有子对象的派生类的构造函数
类中的数据成员除了标准型(int, char等)或系统提供的类型(如string)外,类中的数据成员还可以包括类的对象,例如以上例为基础,可以在声明一个类时包含这样的数据成员:
Student s1 ; //Student是已声明的类名,s1是Student类的对象
1: class Student //声明基类,为简化,在上例的基础上去掉成员变量 char sex
2: {
3: public:
4: Student ( int n , string nam )
5: {
6: ...
7: }
8: ...
9: };
10:
11: class Student1 : public Student //声明公用的派生类
12: {
13: public:
14: Student1 ( int n , string nam , int n1 , string nam1 , int a , string ad )
15: : Student ( n , nam ) , monitor ( n1 , nam1 ) //派生类的构造函数
16: {
17: age = a ;
18: addr = ad ;
19: }
20: private:
21: Student monitor ; //派生类中含有基类的对象
22: int age ;
23: string addr ;
24: };

1.3 多层派生时的构造函数
一个类不仅可以派生出一个派生类,派生类还可以继续派生,形成派生的层次结构。通过例子来说明:
1: class Student //声明基类
2: {
3: public:
4: Student ( int n , string nam ) //基类的构造函数
5: {
6: num = n ;
7: name = nam ;
8: }
9: protected: //基类的保护数据成员
10: int num ;
11: string name ;
12: };
13:
14: class Student1 : public Student //声明公用派生类Student1
15: {
16: Student1 ( int n , string nam , int a ): Student( n ,nam ) //派生类的构造函数
17: {
18: age = a ; //函数体内只对新增的数据成员初始化
19: }
20: private: //派生类的私有数据成员
21: int age ;
22: };
23:
24: Student2 : public Student1 //声明间接公用派生类Student2
25: {
26: public:
27: Student2(int n ,string nam , int a , int s ): Student1( n , nam ,a ) //间接派生类的构造函数
28: {
29: score = s ; //函数体内只对新增的数据成员初始化
30: }
31: private:
32: int score ; //间接派生类新增数据成员
33: };
Student2( int n , string nam , int a , int s ):Student1( n , nam , a )
Student2( int n , string nam , int a , int s ) : Student( n , nam ),Student1(n , nam , a )
1.4 派生类构造函数的特殊形式
有两种特殊形式:
(1)当不需要对派生类新增的数据成员进行任何的初始化操作时,派生类构造函数的函数体可以为空。此时派生类构造函数的作用只是为了将参数传递给基类的构造函数和子对象,并在执行派生类的构造函数时调用基类的构造函数和子对象的构造函数。
(2)如果在基类中没有定义构造函数,或是定义了没有参数的构造函数,那么,在定义派生类的构造函数时可以不写基类的构造函数。在调用派生类的构造函数时,系统会自动首先调用基类的默认构造函数。
2 派生类的析构函数
析构函数的作用是在对象撤销之前,进行必要的清理工作。同样的,派生类是不能继承基类的析构函数的,也需要通过派生类的析构函数去调用基类的析构函数。在派生类中可以根据需要定义自己的虚构函数,用来对派生类中所增加的数据成员进行清理工作。基类的清理工作仍然由基类的析构函数负责,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理。
调用的顺序与构造函数相反:先执行派生类自己的析构函数,对派生类新增加的成员进行清理,然后调用子对象的析构函数,对子对象进行清理,最后调用基类的析构函数,对基类进行清理。
C++学习之路—继承与派生(二):派生类的构造函数与析构函数的更多相关文章
- C++学习之路—继承与派生(一):基本概念与基类成员的访问属性
(本文根据<c++程序设计>(谭浩强)总结而成,整理者:华科小涛@http://www.cnblogs.com/hust-ghtao,转载请注明) 1 基本思想与概念 在传统的程序设计 ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- C++学习笔记(6)----基类和派生类的构造函数和析构函数的执行顺序
基类和派生类:构造函数和析构函数的执行顺序 在Visual Studio中,新建控制台工程,构造类如下: #include<iostream> using namespace std; c ...
- C++:派生类的构造函数和析构函数的调用顺序
一.派生类 在C++编程中,我们在编写一个基类的派生类时,大致可以分为四步: • 吸收基类的成员:不论是数据成员还是函数成员,派生类吸收除基类的构造函数和析构函数之外的全部成员. • 改造基类函数:在 ...
- C++:派生类的构造函数和析构函数
4.2 派生类的构造函数和析构函数4.2.1 派生类构造函数和析构函数的执行顺序 通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数:当撤销派生类对象时,则先执行派生类 ...
- cc28c_demo.cpp,派生类的构造函数和析构函数-代码示范3
cc28c_demo.cpp,派生类的构造函数和析构函数-代码示范3 //派生类的构造函数和析构函数//派生类的构造函数(执行步骤)//--执行基类的构造函数//--执行成员对象的构造函数//--执行 ...
- C++学习之路—继承与派生(四)拓展与总结
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 1 拓展部分 本节主要由两部分内容组成,分 ...
- C++学习之路—继承与派生(三):多重继承与虚基类
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...
- 【温故知新】——BABYLON.js学习之路·前辈经验(二)
前言:在上一篇随笔BABYLON.js学习之路·前辈经验(一)中回顾了组内同事们长时间在Babylon开发实践中的总结出的学习之路和经验,这一篇主要对开发中常见的一些功能点做一个梳理,这里只作为温故知 ...
随机推荐
- C++拾遗
1三个概念 字符串字面值是一串常量字符(是一个常量),字符串字面值常量用双引号括起来的零个或多个字符表示,为兼容C语言,C++中所有的字符串字面值都由编译器自动在末尾添加一个空字符.字符串字面值的类型 ...
- (step8.2.2)hdu 2509(Be the Winner——简单博弈)
题目大意:输入一个整数n,表示火柴堆数(原题其实指的是苹果堆数,但是为了尽量与模板保持一致,所以在这里理解为火柴堆数....其实理解为什么都没关系, 重要的是,理解就行....).在接下来的一行中,有 ...
- UVA 10603 Fill(正确代码尽管非常搓,网上很多代码都不能AC)
题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=1544">click here~ ...
- MySQL分组数据
分组 理解分组能够看例如以下一个样例,首先我们打印出products表例如以下 从上面的表中能够看出.每一个vendor都有若干个产品,那么怎么一次统计每一个vendor有多少个产品呢? 这里就能够使 ...
- block 解析 - 形参变量
block形参 之前漏了一篇block形参的介绍,这里给补上. block形参就是定义block带的参数,和函数的参数使用一样,我们可以在block随意使用修改block形参. 我们来看个例子: 我们 ...
- Hadoop源码解析之: TextInputFormat如何处理跨split的行
我们知道hadoop将数据给到map进行处理前会使用InputFormat对数据进行两方面的预处理: 对输入数据进行切分,生成一组split,一个split会分发给一个mapper进行处理. 针对每个 ...
- C# 客户端服务端的编写
客户端的代码 class client { public void mehod() { TcpClient tcp = new TcpClient(); tcp.Connect(IPAddress.P ...
- javascript每日一练(六)——事件一
一.event对象 var oEvent = ev || event;//获取事件对象 oEvent.clientX oEvent.clientY//获取鼠标坐标 oEvent.cancelBubbl ...
- 一天一个类,一点也不累 之 LinkedList
我们的口号是,一天一个类,一点也不累 .. 今天要讲的是---LinkedList 首先,还是看看他的组织结构 Class LinkedList<E> java.lang.Object j ...
- java--多线程之Runnable
引读: 上一篇博文中讲了Thread的继承,存在一个问题就是,如果类本身已经继承了某个父类,又要继承Thread,导致多重继承. [但是我们知道接口是实现多重继承的重要方式].java提供了Runna ...