当前课程知识点:C++语言程序设计进阶 >  第七章 继承与派生 >  基类与派生类类型转换 >  基类与派生类类型转换

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

基类与派生类类型转换在线视频

基类与派生类类型转换

类型转换

例7-3 类型转换规则举例

#include <iostream>
using namespace std;
class Base1 { //基类Base1定义
public:
    void display() const {
        cout << "Base1::display()" << endl;
    }
};
class Base2: public Base1 { //公有派生类Base2定义
public:
    void display() const {
        cout << "Base2::display()" << endl;
    }
};
class Derived: public Base2 { //公有派生类Derived定义
public:
    void display() const {
        cout << "Derived::display()" << endl;
    }
};

例7-3 类型转换规则举例

void fun(Base1 *ptr) {  //参数为指向基类对象的指针
    ptr->display();     //"对象指针->成员名"
}
int main() {    //主函数
    Base1 base1;    //声明Base1类对象
    Base2 base2;    //声明Base2类对象
    Derived derived;    //声明Derived类对象

    fun(&base1);    //用Base1对象的指针调用fun函数
    fun(&base2);    //用Base2对象的指针调用fun函数
    fun(&derived); //用Derived对象的指针调用fun函数

    return 0;
}



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

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

基类与派生类类型转换课程教案、知识点、字幕

大家好

欢迎回来继续学习

C++语言程序设计

这一节呢

我们来学习类型转换

现在我们要学的类型转换呢

是基类与派生类之间的

那么我们来看看

基类与派生类

这两个有密切关联的类之间

有没有一些

必然的可转换规律呢

当然是有的

首先

我们本能地想到

既然派生类

全盘照收了基类的内容

全都继承过来了

那是不是一个派生类的对象

就可以当基类对象用呢

公有继承的情况下

确定是这样的

公有派生类的对象

它是可以被当做基类对象使用的

但是反过来是不行的

为什么呢

因为经过派生以后

派生类的东西

比基类里面的东西多

但是基类里面原有的内容

经过公有派生

就都拿到派生类中来了

而且公有派生

使得基类的对外访问接口

是保持不变的

所以呢

派生类对象

它可以隐含转换为基类的对象

派生类的对象

可以初始化基类的引用

派生类的指针

可以隐含转换为基类的指针

但是呢

这样经过转换以后

通过基类的对象名 指针

就只能使用从基类

继承的成员

派生类新增的成员

那就不能使用了

现在我们来看一个例子

这个例子很有意思

我们想利用这个类型转换规则

编写一个非常通用的显示函数

那么我们这个希望

它特别通用的这种

这种这种很好的愿望

能实现吗

拭目以待

在这里我们定义了Base1

作为基类

然后定义Base2

以公有方式继承了Base1

然后Derived再次继承Base2

也是公有方式

这样呢

就是Base1派生出Base2

Base2又派生出Derived

每个类都有一个

同名的display函数

但是呢

函数体执行的功能各不相同

我们用输出一行

不同的字符串来模拟

它的功能各不相同

接下来呢我们希望

能够写一个通用的显示函数fun

我们知道

如果这个参数类型是基类的指针

那么实参就可以是什么

是派生类的地址

我们知道用派生类的地址

是可以初始化

公有基类的指针的

所以我们期望用这个指针

在运行时

根据需要指向不同的派生对象

然后调用display函数

希望它能够调用到

各个派生类对象

自己的display函数

看看事实是不是这样呢

现在我们通过单步运行

看一下 观察一下这个情况

现在我们通过调试方式

单步跟踪运行进来

在主函数中呢

看到我们构造了这个

Base1的对象

Base2的对象

和Derived对象
然后第一次调用fun函数的时候

将Base1的地址传过去

那进到这里面了

我们这个ptr

指向的是Base1的对象

然后看它调用哪个函数去了

进到display函数里面

再进到

Base1的display函数里面了

好 执行完了回来

接下来呢

给它再传一个Base2的对象

地址
Base2对象地址

现在把它传进去

现在我们知道

这个指针

虽然它是Base1类型的指针

但是它指向的对象

是Base2类型的了

调用谁的display函数呢

跟踪进去

它还是调用了

Base1的display函数

这个没有达到

我们希望的这个理想状态

再观察一次

当将Derived地址给它的时候

走到哪儿去了

进到fun函数里面

这个ptr呢得到了Derived地址

指向的是Derived的对象

结果呢

它还是进到

Base1的display函数里面了

所以完全没有达到

我们期望的这个效果

没有达到这个期望的效果

那么看一下运行结果呢

确实都是调用的

Base1的display函数

运行结果

刚才看的是这个样子

所以没有达到这个效果

但是呢

我们看到这个程序以后

我们会期望这个效果

这种直接的期望

跟得到的结果不一样

使得程序的可读性很不好

所以在这儿建议大家

不要重新定义

继承而来的非虚函数

什么是非虚函数呢

虚函数我们还没有学

第八章讲虚函数

那当然现在的函数

这些display都不是虚函数

那么我们必要重新

用同样的名字去定义

因为我们这样的话就期望

它指针指向各自对象的时候

表现的不一样

但是达不到这个期望

那是不是我们这个期望

就一定达不到呢

是达得到的

只要我们用虚函数

就可以解决这个问题了

这个问题呢

我们先留着

第八章就会解决的

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章小结

-综合实例

--综合实例

-实验十二

--实验十二

- 第十二章讲义

基类与派生类类型转换笔记与讨论

也许你还感兴趣的课程:

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