当前课程知识点:C++语言程序设计进阶 >  第七章 继承与派生 >  派生类的构造和析构 >  派生类的构造函数

返回《C++语言程序设计进阶》慕课在线视频课程列表

派生类的构造函数在线视频

派生类的构造函数

派生类的构造函数

建议

若不继承基类的构造函数

单继承

单继承时构造函数的定义语法

派生类名::派生类名(基类所需的形参,本类成员所需的形参):
基类名(参数表), 本类成员初始化列表
{
	//其他初始化;
};

单继承时的构造函数举例(补7-3)

#include<iostream>
using namespace std;
class B {
public:
    B();
    B(int i);
    ~B();
    void print() const;
private:
    int b;
};

B::B() {
    b=0;
    cout << "B's default constructor called." << endl;
}
B::B(int i) {
    b=i;
    cout << "B's constructor called." << endl;
}
B::~B() {
    cout << "B's destructor called." << endl;
}
void B::print() const {
    cout << b << endl;
}

class C: public B {
public:
    C();
    C(int i, int j);
    ~C();
    void print() const;
private:
    int c;
};
C::C() {
    c = 0;
    cout << "C's default constructor called." << endl;
}
C::C(int i,int j): B(i), c(j){
    cout << "C's constructor called." << endl;
}

C::~C() {
    cout << "C's destructor called." << endl;
}
void C::print() const {
    B::print();
    cout << c << endl;
}

int main() {
    C obj(5, 6);
    obj.print();
    return 0;
}

多继承

多继承时构造函数的定义语法

派生类名::派生类名(参数表) : 
基类名1(基类1初始化参数表), 
基类名2(基类2初始化参数表), 
...
基类名n(基类n初始化参数表), 
本类成员初始化列表
{
        //其他初始化;
};

派生类与基类的构造函数

多继承且有对象成员时派生的构造函数定义语法

派生类名::派生类名(形参表):
基类名1(参数), 基类名2(参数), ..., 基类名n(参数), 
本类成员(含对象成员)初始化列表
{
        //其他初始化
};

构造函数的执行顺序

  1. 调用基类构造函数。

  2. 对初始化列表中的成员进行初始化。

  3. 执行派生类的构造函数体中的内容。



下一节:派生类的构造函数举例

返回《C++语言程序设计进阶》慕课在线视频列表

派生类的构造函数课程教案、知识点、字幕

大家好

欢迎回来继续学习

C++语言程序设计

这一节呢

我们来学习

怎么写派生类的构造函数

大家知道

每个类的构造函数

是负责自己

这个类的对象的初始化的

那么派生类

把基类的所有数据成员

都继承过来了

构造派生类对象的时候

这些继承过来的成员

可怎么初始化呀

它应该不归

派生类的构造函数管吧

好象也管不了吧

那么这个问题怎么解决呢

实际上呢

在默认的情况下

确实这个基类的构造函数

它是不被继承的

派生类呢

需要编写自己的构造函数

而且

派生类自己的构造函数

还需要负责去

向基类的初始化功能传递参数

就是把基类

那些继承过来的成员

初始化需要的参数

传给基类的构造函数

由基类的构造函数

去完成那些初始化工作

由派生类构造函数的函数体

和它的初始化列表

来完成本类新增成员的构造

但是呢

C++11呢

在语法上有了

很好用的一个新规定

就是可以用using语句

继承基类的构造函数

也就是说

我们连基类的构造函数

都可以继承过来

但是

这个并不是总适用的

它一般来讲

只适用于派生类

很少增加新的数据成员

或者不增加新的数据成员的情况

因为呢

这样继承过来的构造函数

它只能初始化

从基类继承的成员

派生类新增的成员

就完全不能够通过构造函数

初始化了

那如果说

这个时候派生类新增成员

它定义了内类的初始值

那就可以用内类的初始值

去初始化它

如果没有定义内类的初始值

那就只能按默认的方式

初始化了

对于基本类型的成员来说

默认的方式初始化

就是不进行初始化

里面会是垃圾数据的

那么使用这个using关键字

它的语法形式在这儿列出来

using后面呢

我们列出基类名

还有作用域分辨符

还有它的基类构造函数名

这样写就可以了

虽然我们用using

可以继承基类的构造函数

貌似比较方便

但是我们也看到了

对于派生类新增的成员

它是无能为力的

所以建议呢

如果你的派生类

需要对自己新增的成员

进行可定制的初始化

也就是说

可以用构造函数的参数

去指定的这种初始化

那么最好还是不用

继承基类的构造函数

自己来写构造函数

但是这种情况下

那些从基类继承过来的成员

到底怎么去初始化呢

我们来看看

派生类的构造函数

有哪些必须要完成的任务

如果我们不继承基类的构造函数

那么对于派生类

新增的成员来说

当然我们用派生类

定义的构造函数进行初始化

毫无问题

那么从基类继承过来的成员呢

大家也不用担心

这个时候呢

C++的机制会自动调用

基类的构造函数进行初始化

但问题来了

调用基类的构造函数进行初始化

这件事是自动的

可是基类构造函数

需要的参数从哪儿来呢

当然没有别的地方可以来

只能由派生类的构造函数

去传递给基类的构造函数

所以派生类的构造函数

还有一个重要任务

就是需要给基类的构造函数

传递参数

如果派生类只有一个

直接基类的情况

那就是单继承的情况

在单继承的情况下呢

派生类的构造函数

只要给一个直接基类传递参数

就可以了

那么这个就是单继承情况下的

派生类构造函数的定义的语法

我们看呢

这个时候

这个派生类

它的构造函数的参数表里头

可能就需要多写点参数了

除了本类成员初始化

所需要的形参以外

那么要初始化那些从基类

继承过来的成员

要调用基类的构造函数

那么也需要参数啊

这一些参数从哪儿获得呢

一块都得列在

派生类构造函数的参数列表里面

然后在这个

派生类的构造函数的函数头之后

大家看有一个冒号

冒号之后呢

应该是初始化列表的位置 对吧

那么在初始化列表的最开头位置

就要首先列出基类名

和基类构造函数

所需要的参数表

然后再列出

本类成员的初始化列表

那类体中呢

当然是其他与初始化

相关的语句

下面这个例题呢

演示了单继承情况下

派生类的构造函数

以及构造函数的调用过程

在这里呢

我们定义了类b作为基类

这个类自己定义了默认构造函数

和有一个参数的构造函数

另外呢

还定义了析构函数

以及一个print函数

这个print函数

由于它是不改变对象状态的

所以我们把它定义成const函数

然后再看这个C类

以公有方式继承了B类

它自己也定义了

无参数的默认构造函数

以及有两个参数的构造函数

析构函数

和它自己的print函数

是const类型的

那我们在主函数中呢

构造一个C类的对象

看看这个构造过程中

构造函数

到底是按照什么顺序调用的

现在我们用单步执行跟踪进来

按f11

进到C类的构造函数里面

在这儿

由于它继承了B类

所以呢

它需要给B类的构造函数

传递参数

那么这里初始化列表列出来了

那么由于这个初始化列表里面

有了参数

所以B类的

要一个参数的构造函数

就应该被调用

应该进到

B类的这个构造函数中去

我们单步执行一次看看

是不是这样

按f11

果然进到了

B类的这个构造函数里面来

执行完了这个构造函数以后

给B类

继承过来的对象B初始化以后

回到C类构造函数这儿

这个时候呢

就该对C类自己定义的成员

进行初始化了

我们看目前C类自己的成员这儿

还是垃圾数据

还没有被初始化

我们执行一步以后看

这个已经初始化了

回到主函数

下面呢

我们来看一下

在多继承的情况下

派生类的构造函数该怎么写

在多继承的情况下呢

派生类构造函数

它的初始化列表中呢

就需要列出所有的基类

以及基类构造函数

它需要的初始化参数

现在我们来考虑一下呢

如果派生类

没有写构造函数会怎么样

如果一个没有继承关系的类

不写构造函数

那么我们知道没有关系

会有隐含生成的默认构造函数

只要你构造这个

类的对象的时候

你不需要初始化

那就没有问题

那么当有继承的情况下

情况就要复杂一些

当基类有默认构造函数的时候

派生类的构造函数

就可以不向基类的构造函数

传递参数

那么你不传递参数

构造对象的时候

就会自动调用基类那个

无参的默认构造函数

构造派生类对象的时候呢

如果需要执行

基类中带参数的构造函数

那么这个时候

派生类的构造函数

就要为基类的构造函数

去传递参数

在第四章呢

我们学了类的组合

现在我们又学了类的继承

如果我们写一个类

既有组合 又有继承的时候

那么这个类的构造函数

该怎么写

现在我们来看一下

那有多继承

又有对象成员的时候

也就是又有继承

又有组合的时候

那么派生类构造函数

该怎么写呢

也很简单

把我们前面学过的东西

全部加到一起就行了

那看看这个语法

就是所有的基类

以及基类的构造函数

需要的参数都列在这儿

所有的本类的对象成员

以及它们初始化需要的参数

也都列在这儿

本类的成员初始化列表里面

当然它就包含了对象成员

也包含了基本类型的数据成员

所以就是那句话

把我们前面学过的所有东西

都加在一起就行了

我们知道了构造函数怎么写

那么这些构造函数的调用次序

又是什么样的呢

特别是既有继承

而且是多继承

还要有组合的情况下

到底哪些构造函数先调用

哪个构造函数后调用

它按什么样的次序来调用呢

我们来看一下这个次序问题

那实际上呢

这个次序大家想象也会想象的到

从哪儿继承了

先把继承的问题解决 对吧

用什么部件构造的

你先把部件解决

然后你才能够得到最终的成品

是不是呢

道理就是这个

所以第一步呢

就是调用所有的基类的构造函数

要有多个基类怎么调用呢

它调用顺序

就按照它们被继承的时候

声明的顺序从左向右调用

那 接下来呢

就该对初始化列表里面的成员

进行初始化了

那么这个初始化列表里面的成员

就会包含着对象成员

和基本类型的成员

顺序是按什么呢

按照这些成员在类中定义的顺序

那这里面的对象成员

要进行初始化的时候呢

又会自动调用

它所属类的构造函数

那么这个由初始化列表

为它提供参数

这些都做完了

最后才执行派生类构造函数

也是组合类构造函数

它的函数体里面的内容

C++语言程序设计进阶课程列表:

第七章 继承与派生

-导学

--导学

-继承的基本概念和语法

--继承的基本概念和语法

-第七章 继承与派生--继承的基本概念和语法习题

-继承方式

--继承方式简介及公有继承

--私有继承和保护继承

-第七章 继承与派生--继承方式

-基类与派生类类型转换

--基类与派生类类型转换

-第七章 继承与派生--基类与派生类类型转换

-派生类的构造和析构

--派生类的构造函数

--派生类的构造函数举例

--派生类的复制构造函数

--派生类的析构函数

--第七章 继承与派生--派生类的构造和析构

-派生类成员的标识与访问

--访问从基类继承的成员

--虚基类

-第七章 继承与派生--派生类成员的标识与访问

-小结

--小结

-综合实例

--第七章综合实例

-实验七

--实验七

-第七章讲义

第八章 多态性

-导学

--导学

-第八章 多态性--导学

-运算符重载

--运算符重载的规则

--双目运算符重载为成员函数

--单目运算符重载为成员函数

--运算符重载为非成员函数

-第八章 多态性--运算符重载

-虚函数

--虚函数

--虚析构函数

--虚表与动态绑定

-第八章 多态性--虚函数

-抽象类

--抽象类

--第八章 多态性--抽象类

-override与final

--override与final

-第八章 多态性--override与final

-小结

--第八章小结

-综合实例

--第八章综合实例

-实验八

--实验八

- 第八章讲义

第九章 模板与群体数据

-导学

--导学

-模板

--函数模板

--类模板

-第九章 模板与群体数据--模板

-线性群体

--线性群体的概念

-第九章 模板与群体数据--线性群体

-数组

--数组类模板

--例9-4数组类应用举例

-链表

--链表的概念与结点类模板

--链表类模板

-第九章 模板与群体数据--链表

-栈

--栈类模板

--栈类模板课后习题

--例9-9 栈的应用

--例9-9 栈的应用课后习题

-队列

--队列类模板

-第九章 模板与群体数据--队列

-排序

--排序概述

--插入排序

--选择排序

--交换排序

-第九章 模板与群体数据--排序

-查找

--查找

--查找课后习题

-小结

--小结

-综合实例

--综合实例

-实验九

--实验九

- 第九章讲义

第十章 泛型程序设计与C++标准模板库

-导学

--导学

-泛型程序设计及STL的结构

--泛型程序设计的基本概念

--STL简介

-第十章 泛型程序设计与C++标准模板库--泛型程序设计及STL的结构

-迭代器

--迭代器

-第十章 泛型程序设计与C++标准模板库--迭代器

-容器的基本功能与分类

--容器的基本功能与分类

-第十章 泛型程序设计与C++标准模板库--容器的基本功能与分类

-顺序容器

--顺序容器的基本功能

--顺序容器的特征

--顺序容器的插入迭代器与适配器

--第十章 泛型程序设计与C++标准模板库--顺序容器

-关联容器

--关联容器分类和基本功能

--集合

--映射

--多重集合和多重映射

-第十章 泛型程序设计与C++标准模板库--关联容器

-函数对象

--函数对象

--函数适配器

-算法

--算法

-小结

--第十章小结

-综合实例

--综合实例

-实验十

--实验十

- 第十章讲义

第十一章 流类库与输入/输出

-导学

--导学

-I/O流的概念及流类库结构

--I/O流的概念及流类库结构

-第十一章 流类库与输入/输出--I/O流的概念及流类库结构

-输出流

--输出流概述

--向文本文件输出

--向二进制文件输出

--向字符串输出

-第十一章 流类库与输入/输出--输出流

-输入流

--输入流概述

--输入流应用举例

--从字符串输入

-第十一章 流类库与输入/输出--输入流

-输入/输出流

--输入/输出流

-第十一章 流类库与输入/输出--输入/输出流

-小结

--小结

-综合实例

--综合实例

-实验十一

--实验十一

- 第十一章讲义

第十二章 异常处理

-导学

--第12章导学

-异常处理的思想与程序实现

--异常处理的思想与程序实现

-第十二章 异常处理--异常处理的思想与程序实现

-异常处理中的构造与析构

--异常处理中的构造与析构

-第十二章 异常处理--异常处理中的构造与析构

-标准程序库异常处理

--标准程序库异常处理

-第十二章 异常处理--标准程序库异常处理

-小结

--第12章小结

-综合实例

--综合实例

-实验十二

--实验十二

- 第十二章讲义

派生类的构造函数笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。