| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C++继承与多态 -> 正文阅读 |
|
[C++知识库]C++继承与多态 |
? ? ? ? C++是一款面向对象的语言,对象是可以物化的实体,拥有自己的特性与行为,像车子有外形,内核,可以加速减速。而车子又分为保时捷与宝马、奔驰等等。我们想要描述一个车子对象的特征,就需要创建一个类,若为每一种车创建一个类,会使效率下降,而不同车子之间既有共性又有特性,因此,便产生了派生类。 一、派生类的继承方式派生类(子类)继承了基类(父类)的特性,同时它可以添加自己的诸多特点。继承的方式有以下三种 ? ?既:派生类对基类的继承小于等于基类的数据(包括成员变量与成员函数) 无论用那种方式继承,派生类对基类数据的访问都只限于public和protected区域,而不能访问private区域。如果要访问基类的private区域,可以在基类的public或protectd区域里面创建接口
派生类derived正常情况下访问不到m_a,但添加了func这个接口,即可通过func来访问。 二、构造派生类对象构造一个对象,首先调用的是构造函数,派生类继承了除构造函数和析构函数的其他非私有部分,但派生类仍是属于基类的,所以如果创建一个派生类对象,那么构造函数和析构函数的调用顺序如下
可知,派生类的创建先调用了基类的构造函数和其部分成员变量,再调用派生类构造函数及其部分成员变量,如果基类中还有对象,则应先调用成员对象的构造函数,其中,析构函数的调用顺序与构造函数相反。? 三、多态的初步形成如果派生类中有和基类中重命名的成员,则有三种可能性:重载,隐藏和覆盖。 1、重载
以上是重载的实现,C++允许在同一作用域中声明几个类似的同名函数,通过函数的参数个数,种类与排列顺序来区分。函数的返回值类型可相同可不同(函数的返回值类型不是区分函数的条件)。C++的函数重载是在编译时完成的,既C++编译器为根据参数的种类,数量或者排列顺序不同将函数区分开来。 2、函数隐藏? 函数隐藏,是指C++中派生类覆盖基类同名成员函数(不考虑参数列表)
?即:即使派生类继承了基类的show函数,但派生类中的show函数将基类中的show函数替换掉了,但如果用Base类的指针指向show函数,还是能找到Base类的原函数的,即使它指向的是一个派生类对象(派生类对象本就属于基类,基类指针优先在基类中寻找函数,找到所需函数即停止寻找)。 三、函数覆盖
? ? ? ? 当父类函数show()为virtual函数时,调用它的对象类型为指针类型指向的类型,这是一个动态的过程,当类中出现virtual函数时,在编译时期会为对象产生一个虚函数表,将virtual的成员放在里面,我们已经知道,基类的构造早于派生类,所以在创建虚函数表时,将基类的Show函数先放入改表中,到派生类时,派生类中的Show函数(若基类存在virtual函数类型,则系统自认派生类函数为虚函数)将基类的Show函数覆盖,因此,我们用Base虚指针创建Derived对象,再调用其Show函数时,看到的是派生类中的Show函数。 在次,我对基类和派生类中一些指针和引用情况进行简述。 派生类对象可以赋值给基类对象,但基类对象就不可以赋值给派生类对象。好比保时捷肯定是一个车,但你不能见到一个车就说它是保时捷。 基类指针(引用)可以指向派生类对象,但只能访问派生类中基类部分的方法,不能访问派生类部分的方法,派生类指针(引用)不可以指向基类对象,解引用可能出错,因为派生类的一些方法可能基类没有。 ?四、虚函数?下面我们借助一段代码来说明虚函数的一些问题
?我们运行程序,得到的会是B的foo函数,如果基类中foo函数不加virtual,那么A的指针将无法访问B中的foo,在将A中的foo定义为虚函数后,如果想用B创建的对象来访问A中的foo函数,在foo函数的前面加上A::作用域即可。
该段代码中,派生类没有定义虚析构函数,会造成delete父类的指针时只调用父类的析构函数,而不调用子类的析构函数。(前面提到过,基类的构造函数和析构函数是不被派生类继承的,基类的指针也就无法指向派生类的析构函数),此时delete a[0],就不会调用虚析构函数,如果在派生类构造函数中存在内存释放,不被调用,就会造成内存泄漏。所以,我们需要在基类中的析构函数前加上virtual时,基类的指针就会先调用派生类的析构函数(存在于虚函数表中),再返回自己的基类中调用基类析构函数。也就是说虚函数的指针和引用可以找到对应函数,而不仅是执行定义类的函数。但,构造函数不能声明为虚函数,因为在执行构造函数前对象没有创建,因此编译时产生的虚函数表里没有构造函数,我们也无法得知调用那个构造函数了。 纯虚函数 纯虚函数的简单模板如下:
纯虚函数可以是类中的任意函数,只要类中出现纯虚函数,则该类被称为抽象类,即不可以创建对象,只能作为基类模板使用。但即使是抽象类,编译器仍会编译改类,所以我们需要在类外对纯虚函数进行声明。 虚继承 虚继承主要解决的是一个派生类如果继承多个基类,同时基类中又有几类继承同一类的话,在创建对象时,会产生二义性。
?如本段代码,如果我们不在类B和类C继承A时加上virtual? seta函数在运行时,将发生错误,因为它有两个可选的途径,这会造成二义性。添加virtual之后,D类创建对象时,则会选择最近的A类来创建,并且只产生一份m_a的数据。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 13:58:44- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |