行业知识
【C++】多态
���梓慕:个人主页
个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》《算法》
每一个不曾起舞的日子,都是对生命的辜负
目录
前言
1.多态的概念
2.多态的定义及细节
2.1虚函数
2.2虚函数的重写
2.2.1虚函数重写的两个例外
2.3普通调用和多态调用的区别
2.4『 final』和『 override』关键字(C++11)
2.4.1『 final』
2.4.2『 override』
2.5重载、重写(覆盖)、隐藏(重定义)的对比
3.抽象类
3.1概念
3.2意义
3.3『 接口继承』和实现继承
4.多态的原理
4.1虚函数表
4.2多态的原理
4.3动态绑定和静态绑定
4.3.1静态绑定(不构成多态)
4.3.2动态绑定(构成多态)
4.4单继承和多继承关系的虚函数表
4.4.1单继承关系的虚函数表
4.4.2多继承关系的虚函数表
4.4.3利用代码打印出虚函数表
前言
本篇文章博主将与大家共同学习多态的相关内容,并且会对之前继承的学习作补充。
欢迎大家收藏以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。
=========================================================================
GITEE相关代码:樊飞 (fanfei_c) - Gitee.com
=========================================================================
1.多态的概念
通俗来说,就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态 。
举个例子:比如买票这个行为 ,当普通人买票时,是全价买票;学生买票时,是半价买票;
如:
2.多态的定义及细节
在继承中要构成多态需要两个条件:
- 必须通过『 父类』的『 指针』或者『 引用』调用虚函数;
- 被调用的函数必须是『 虚函数』,且子类必须对父类的虚函数进行『 重写』;
对于上面新出现的两个概念做解释:
2.1虚函数
- 被virtual修饰的类『 成员函数』称为虚函数。
2.2虚函数的重写
- 子类中有一个跟父类『 完全相同』的虚函数(即子类虚函数与父类虚函数的返回值类型、函数名、参数『 类型』完全相同),称子类的虚函数重写了父类的虚函数。
注意:在重写父类虚函数时,子类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后,父类的虚函数被继承下来了,所以在子类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用。
2.2.1虚函数重写的两个例外
(1)协变(父类与子类函数返回值类型不同)
协变是子类虚函数与父类虚函数返回值类型不同,但子类和父类的返回值类型也必须是父子关系指针和引用。
如:
class A {};class B : public A {};class Person {public:virtual A* f() { return new A; }};class Student : public Person {public:virtual B* f() { return new B; }};所以如果有人问:有关虚函数的重写,两个虚函数的返回值是必须相同的么?
你就知道这是个坑了,因为有『 协变』这一特殊情况,返回值类型不相同也可能满足虚函数重写。
(2)析构函数的重写(父类与子类析构函数名字不同)
我们知道,编译器对析构函数的名称会做特殊处理,编译后析构函数的名称统一处理成destructor(),这样就变相的满足了函数名相同了。
所以我们一般都给析构函数前加上virtual关键字,这样如果有子类继承,析构重写正好,没有子类继承也不影响。
有的同学可能会有疑问:为什么一定要重写父类的析构函数呢?
class Person {public:~Person() { cout
- 子类中有一个跟父类『 完全相同』的虚函数(即子类虚函数与父类虚函数的返回值类型、函数名、参数『 类型』完全相同),称子类的虚函数重写了父类的虚函数。
- 被virtual修饰的类『 成员函数』称为虚函数。
上一篇:饥荒怎么取消服务器创建?
下一篇:赤壁怎么连接不上服务器?