c++_ 多态

目录

一.多态

1.1多态(polymorphism)的概念

1.2实现多态还有两个必须重要条件:

[1.3 重载 和 虚函数的重写/覆盖 和 隐藏 的比对](#1.3 重载 和 虚函数的重写/覆盖 和 隐藏 的比对)

[1.4 协变(了解)](#1.4 协变(了解))

[1.5 析构函数的重写](#1.5 析构函数的重写)

[1.6 override 和final关键字](#1.6 override 和final关键字)

二.纯虚函数和抽象类

[三. 多态的原理](#三. 多态的原理)

3.1虚函数表指针

[3.2 虚函数表概念](#3.2 虚函数表概念)


一.多态

1.1多态(polymorphism)的概念

多态(polymorphism)的概念:多态分为 编译时多态 **(静态多态 )**和 运行时多态 (动态多态)

编译时多态 ,(静态多态) 主要就是 函数重载 和 函数模板,他们传不同类型的参数就可以调用不同的函数,通过参数不同达到多种形态。之所以叫 编译时多态(动态多态),是因为他们 实参传给形参的参数匹配是在 编译时完成的,我们把编译时⼀般归为静态,运行时归为动态。


1.2实现多态还有两个必须重要条件:

~ 第⼀必须是 基类的指针或引用 ,因为只有 基类的指针 或 引用 才能既指向派生类对象

~ 第二 派生类 必须对 基类 的虚函数重写/覆盖 ,重写或者覆盖了,派生类才能有不同的函数,多

态的不同形态效果才能达到

注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派⽣类依旧保持虚函数属性),但是该种写法不是很规范。

不规范的写法,考试容易出现

规范写法:比如

不规范的写法:比如


1.3 重载 和 虚函数的重写/覆盖 和 隐藏 的比对

虚函数的 重写/覆盖:派生类中有⼀个跟基类完全相同的虚函数(即派生类虚函数 与 基类虚函数的返回值类型、函数名字、参数列表完全相同),称派生类的虚函数重写了基类的虚函数。

重载:函数名字相同、参数的 类型 和 个数不同、返回值都可以。

隐藏 :函数名字相同 、但不构成 重新/覆盖 。


1.4 协变(了解)

派生类重写基类虚函数时,与基类虚函数 返回值类型不同。

1.5 析构函数的重写

基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同看起来不符合重写的规则,实际上编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统⼀处理成destructor ,所以只要基类的析构函数加了vialtual修饰,派生类的析构函数就构成重写。(知道最后一句就行)


1.6 override 和final关键字

C++11提供了override,可以帮助用户 检测 是否 重写。

我们 不想让 派生类重写这个 虚函数,那么可以用 final 去修饰。


二.纯虚函数和抽象类

在虚函数的后⾯写上 =0 ,则这个函数为纯虚函数。纯虚函数不需要定义实现(实现没啥意义因为要被派生类重写,但是语法上可以实现),只要声明即可。纯虚函数某种程度上强制了派生类重写虚函数,因为 纯虚函数 ,实例化不出对象。比如:

结果:


三. 多态的原理

3.1虚函数表指针

⼀个含有虚函数的类 中都 至少都有⼀个虚函数表指针,因为⼀个类所有虚函数的地址要

被放到这个类对象的虚函数表中,虚函数表也简称虚表。

比如:

3.2 多态的原理

每个实例化的对象,运行时都有自己的虚表,运行时 到指向的对象的虚表中 确定 对应的虚函数的地址 ,这样就实现了 指针或引用 指向基类就调用基类的虚函数,如果 指向派生类就调用派生类对应的虚函数。

父类的虚表地址:

子类的虚表地址:

3.2 虚函数表概念

• 基类对象的虚函数表中 存放 基类所有 虚函数的地址。

• 派生类由两部分构成,继承下来的基类 和 自己的成员。 ⼀般情况下,继承下来的基类中有虚函数表指针,自己就不会再生成虚函数表指针。但是要注意的这里继承下来的基类部分虚函数表指针和基类对象的虚函数表指针不是同⼀个,就像基类对象的成员和派生类对象中的基类对象成员也独立的。

• 派生类中重写的基类的虚函数,派⽣类的虚函数表中对应的虚函数就会被覆盖成派⽣类重写的虚函数地址。派生类的虚函数 表中包含,基类的虚函数地址 ,派生类重写的虚函数地址 ,派生类自己的虚函数地址 三个部分。

• 虚函数表本质是⼀个存虚函数指针的 指针数组。

相关推荐
蜗牛一步步往上爬1 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
张张123y3 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
wo_jack5 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
D e re k ZH5 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶6 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
FRing036 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
雪落漂泊6 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
波力海苔夹心脆6758 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
不会算法的笨小孩8 小时前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常
Hhy_110710 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio