C++有子对象的派生类的构造函数
转载:https://blog.csdn.net/qq1169091731/article/details/50934588?utm_source=blogxgwz6
类的数据成员不但可以是标准型(如int、char)或系统提供的类型(如string),还可以包含类对象,如可以在声明一个类时包含这样的数据成员:
class B{
…
};
class A{
public:
B s1; //B是已声明的类名,s1是B类的对象
…
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这时,s1就是类对象中的内嵌对象,称为子对象(subobject),即对象中的对象。
在派生类中,子对象为基类在派生类中定义的对象。如下列代码:
class Student{
…
};
class Student1:public Student{
private:
Student a; //这里的a即为子对象
…
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
通过例子来说明问题。在上篇博客(C++派生类的构造函数)中的派生类Student1中,除了可以在派生类中要增加数据成员age和address外,还可以增加“班长”一项,即学生数据中包含他们的班长的姓名和其他基本情况,而班长本身也是学生,他也属于Student类型,有学号和姓名等基本数据,这样班长项就是派生类Student1中的子对象。在下面程序的派生类的数据成员中, 有一项monitor(班长),它是基类Student的对象,也就是派生类Student1的子对象。
那么,在对数据成员初始化时怎样对子对象初始化呢?请仔细分析下面程序,特别注意派生类构造函数的写法。
[例11.6] 包含子对象的派生类的构造函数。为了简化程序
以易于阅读,这里设基类Student的数据成员只有两个,即num和name。
#include <iostream>
#include <string>
using namespace std;
class Student//声明基类
{
public: //公用部分
Student(int n, string nam ) //基类构造函数,与例11.5相同
{
num=n;
name=nam;
}
void display( ) //成员函数,输出基类数据成员
{
cout<<"num:"<<num<<endl<<"name:"<<name<<endl;
}
protected: //保护部分
int num;
string name;
};
class Student1: public Student //声明公用派生类Student1
{
public:
Student1(int n, string nam,int n1, string nam1,int a, string ad):Student(n,nam),monitor(n1,nam1) //派生类构造函数
{
age=a;
addr=ad;
}
void show( )
{
cout<<"This student is:"<<endl;
display(); //输出num和name
cout<<"age: "<<age<<endl; //输出age
cout<<"address: "<<addr<<endl<<endl; //输出addr
}
void show_monitor( ) //成员函数,输出子对象
{
cout<<endl<<"Class monitor is:"<<endl;
monitor.display( ); //调用基类成员函数
}
private: //派生类的私有数据
Student monitor; //定义子对象(班长)
int age;
string addr;
};
int main( )
{
Student1 stud1(10010,"Wang-li",10001,"Li-sun",19,"115 Beijing Road,Shanghai");
stud1.show( ); //输出学生的数据
stud1.show_monitor(); //输出子对象的数据
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
运行时的输出如下:
This student is:
num: 10010
name: Wang-li
age: 19
address:115 Beijing Road,Shanghai
Class monitor is:
num:10001
name:Li-sun
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
请注意在派生类Student1中有一个数据成员:
Student monitor; //定义子对象 monitor(班长)
“班长”的类型不是简单类型(如int、char、float等),它是Student类的对象。我们知道, 应当在建立对象时对它的数据成员初始化。那么怎样对子对象初始化呢?显然不能在声明派生类时对它初始化(如Student monitor(10001, “Li-fun”);),因为类是抽象类型,只是一个模型,是不能有具体的数据的,而且每一个派生类对象的子对象一般是不相同的(例如学生A、B、C的班长是A,而学生D、E、F的班长是F)。因此子对象的初始化是在建立派生类时通过调用派生类构造函数来实现的。
派生类构造函数的任务应该包括3个部分:
对基类数据成员初始化;
对子对象数据成员初始化;
对派生类数据成员初始化。
- 1
- 2
- 3
程序中派生类构造函数首部如下:
Student1(int n, string nam,int n1, string nam1,int a, string ad):
Student(n,nam),monitor(n1,nam1)
在上面的构造函数中有6个形参,前两个作为基类构造函数的参数,第3、第4个作为子对象构造函数的参数,第5、第6个是用作派生类数据成员初始化的。
归纳起来,定义派生类构造函数的一般形式为:
派生类构造函数名(总参数表列): 基类构造函数名(参数表列), 子对象名(参数表列)
{
派生类中新增数成员据成员初始化语句
}
执行派生类构造函数的顺序是:
调用基类构造函数,对基类数据成员初始化;
调用子对象构造函数,对子对象数据成员初始化;
再执行派生类构造函数本身,对派生类数据成员初始化。
- 1
- 2
- 3
派生类构造函数的总参数表列中的参数,应当包括基类构造函数和子对象的参数表列中的参数。基类构造函数和子对象的次序可以是任意的,如上面的派生类构造函数首部可以写成
Student1(int n, string nam,int n1, string nam1,int a, string ad): monitor(n1,nam1),Student(n,nam)
编译系统是根据相同的参数名(而不是根据参数的顺序)来确立它们的传递关系的。但是习惯上一般先写基类构造函数。
如果有多个子对象,派生类构造函数的写法依此类推,应列出每一个子对象名及其参数表列。
C++有子对象的派生类的构造函数的更多相关文章
- 【C++继承与派生之二】有子对象的派生类的构造函数
这是我今天看书刚刚看到的,觉着以前对这一块内容了解不多,所以整理一下分享给大家.首先要介绍一下子对象的概念.类的数据成员不仅可以是int.char这样的基本类型,也可以是类对象,如可以包含这样的数据成 ...
- C++学习之路—继承与派生(二):派生类的构造函数与析构函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 由于基类的构造函数和析构函数是不能被继承的,所以 ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- C++学习17派生类的构造函数
基类的构造函数不能被继承,在声明派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数来完成.所以在设计派生类的构造函数时,不仅要考虑派生类新增的成员变量,还要考虑基类的成员变量,要让它们都 ...
- C++:派生类的构造函数和析构函数
4.2 派生类的构造函数和析构函数4.2.1 派生类构造函数和析构函数的执行顺序 通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数:当撤销派生类对象时,则先执行派生类 ...
- 【C++学习之路】派生类的构造函数(三)
三.多层继承的派生类 1.多层继承的派生类只需在构造函数的初始化列表中写出直接基类的构造函数即可 class student { public: student(int n, string nam) ...
- 【C++学习之路】派生类的构造函数(二)
二.有内嵌对象的派生类 1.一般来说,我们会这样定义构造函数 student( int i, string nam, int pid, string pnam, int sid) : person( ...
- 【C++学习之路】派生类的构造函数(一)
一.简单派生类的构造函数 1.所谓简单派生类,就是指派生类中不包含基类的内嵌对象的派生类. 2.一般来说,这样的派生类的构造函数的形式是: student( int i, string nam, in ...
- c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]
说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...
随机推荐
- Android Studio 如何导出和导入自己的常用设置,避免重复制造轮子。加快开发速度
Android Studio 如何导出和导入自己的常用设置,避免重复制造轮子.加快开发速度 作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 在使用 A ...
- python文件操作、查看路径、查看文件名
1 # -*- coding: utf-8 -* # from sys import argv # script,input_file = argv import os file_url = &quo ...
- 深入理解计算机系统 Start && 第一章要点
对此书已经慕名已久了,抽空看了第1,2,3,5章,其他章节等有空闲继续看吧. 我的许多博客是给自己快速复习使用的,比如此读书后感,你可以根据我下面的建议读完原书几章再回来复习一下(或许那时候就没必要回 ...
- JavaScript 时间都去那了(操作时间字符串加减时间)
---给时间充点时间吧--- 时间转换函数: function dateFormat(date, format) { date = new Date(date); var o = { 'M+': da ...
- css动画是否会被js阻塞
css动画是否会被js阻塞 css的动画部分是会被js阻塞的,不过transform的动画则不会受影响. 下面举一个margin-left移动的动画下,启动js阻塞动画的性能图表 <style& ...
- npm 进阶命令知多少(一)
npm命令知多少(一) 前言 作为前端模块化扎展现形式的npm包,已经在前端开发中不可或缺,熟练掌握npm相关内容,也是前端开发者的一门必修课,那么除了npm publish这类常见内容之外,还有哪些 ...
- 原生JDK网络编程- Buffer
Buffer用于和NIO通道进行交互.数据是从通道读入缓冲区,从缓冲区写入到通道中的.以写为例,应用程序都是将数据写入缓冲,再通过通道把缓冲的数据发送出去,读也是一样,数据总是先从通道读到缓冲,应用程 ...
- LG P2389 电脑班的裁员
Description ZZY有独特的裁员技巧:每个同学都有一个考试得分$a_i(-1000 \leq a_i \leq 1000)$,在$n$个同学$(n \leq 500)$中选出不大于$k$段$ ...
- MySQL<=>是什么鬼
官网描述 NULL-safe equal. This operator performs an equality comparison like the = operator, but returns ...
- 学习 | jQuery移动端页面组件化开发(一)
最近在学习移动端组件化开发web页面,其中有好多小细节,值的去思考. 主要介绍JS的思路,具体的代码就不贴了,主要是想表达出一种思路 总体来说 1.入口文件,在入口文件中导入插件,插件样式,jquer ...