c++多态性及多态的内部实现(翁恺c++公开课[23-24])
多态是在父类函数的前面加上 “virtual” 关键字,使子类与父类同名的函数产生一种联系;
多态会用到两个特性:向上造型、动态绑定
向上造型是指:拿一个子类对象当作父类来看待,比如下边代码中的子类Ellipse对象ell当作父类Shape对象来看待;
动态绑定:当我要调用一个函数的时候,运行的时候才知道要调用哪个函数,编译的时候是不确定的;
class Shape
{
public:
Shape();
virtual ~Shape(); //析构为什么会有虚函数
virtual void render();
void move(const XYPos&);
virtual void resize();
protected:
XYPos center;
}; class Ellipse : public Shape
{
public:
Ellipse(float maj, float minr);
virtual void render(); //will define own
protected:
float major_axis,minor_axis;
}; class Circle : public Ellipse
{
public:
Circle(float radius) : Ellipse(radius, radius) {}
virtual void render();
};
...
void render(Shape* p)
{
p->render(); //这里会根据传进来的形参类型,来决定调用哪个类的render函数
}
void func()
{
Ellipse ell(, );
ell.render();
Circle circ();
circle.render();
render(&ell); // 这里是调用的Ellipse的render函数
render(&circ); //这里是调用了Circle的render函数
}
virtual写在函数前面的作用:如果使用指针或引用调用此函数时,只有在编译的时候才知道选哪个类的render函数去调用,我们这里说void render(Shape *p)中的p指针时多态指针,p的形态是不定可能是基类也可能是某一个子类。
多态的实现:
所有的 有virtual的类的对象最头上都会又一个叫vptr的指针指向一个虚函数表(vtable);
这张vtable虚表里的内容是什么呢,是类的所有的有virtual的函数的地址,这张表属于这个类,而不是类的每个对象,这就是说所有对象的vptr的值都是一样的,指向同一个地址;
下面两个图是内存模型:在每个类的虚函数表中发生继承的virtual函数会被替换成自己的,结合上边的代码render(&ell);此时ell->render()时,ell指针的地址+2就是要调用的函数的地址了,所以说,虚函数的实现并不是去判断这个指针是什么类型,这样做的好处就是大大的提升效率。


下面看一些面试官比较喜欢考的题,这种题往往会各种赋值,以达到把你绕晕的效果,这里我们只要记住它的本质就好,顺着本质去捋,再怎么绕也能轻松解开。
考点
- 多态的本质就是vtable(虚函数表),采用指针+n的方式调用虚函数
- 只有通过指针或引用的方式才能去调用 ,通过对象 点 的方式是不会触发多态机制的
目录
- c++(翁恺浙大公开课) 笔记0
- static在c\c++中的作用(翁恺c++公开课[28-29]学习笔记)
- c++对象初始化(翁恺c++公开课[10])
- c++构造函数的初始化列表(翁恺c++公开课[13])
- c++继承:公有、私有、保护
- c++子类父类关系(翁恺c++公开课[15-16]学习笔记)
- c++拷贝构造函数(翁恺c++公开课[26-27]学习笔记)
- c++多态性及多态的内部实现(翁恺c++公开课[23-24])
- c++中的运算符重载operator1(翁恺c++公开课[30]学习笔记)
- c++中的运算符重载operator2(翁恺c++公开课[31-33]学习笔记)
- c++模板(翁恺c++公开课[34-35]学习笔记)
- 最好不要在头文件中写函数定义
c++多态性及多态的内部实现(翁恺c++公开课[23-24])的更多相关文章
- c++中的Exceptions异常处理(翁恺c++公开课[36])
Exceptions用于处理Run-time Error: //文件读取的异常捕获伪代码 try{ open the file; determine its size; allocate that m ...
- c++拷贝构造函数(翁恺c++公开课[26-27]学习笔记)
这节课在p26.拷贝构造中讲的很清楚,建议大家耐心的去看下. 什么时候会发生拷贝构造: 对象之间的初始化赋值 使用对象作为变量进行函数传参(通常使用引用来传参从而减去不必要的拷贝构造,提高效率和代码健 ...
- c++构造函数的初始化列表(翁恺c++公开课[13])
初始化列表形式: class Point { private: const float x,y; Point(float xa = 0.0, flato ya = 0.0):y(ya),x(xa) { ...
- c++对象初始化(翁恺c++公开课[10])
c++对象初始化 就是去调用构造函数来完成初始化操作: 构造函数有无参数的构造函数.有参数构造函数.默认构造函数(编译器给我们实现的)...(拷贝构造函数之后说) 注意:默认构造函数只有在我们自己没有 ...
- c++子类父类关系(翁恺c++公开课[15-16]学习笔记)
关于类的继承有三种:public继承.private继承.protected继承 首先说明,关于类的成员变量.函数的权限有三种(public.private.protected) 我们通常会让所有的成 ...
- c++模板(翁恺c++公开课[34-35]学习笔记)
为什么要有模板(templates):当我们需要一个列表(list),列表中元素可能都为X类型也可能都为Y类型,怎么来实现呢? 定义基类?可以实现,很多情况下可能不够简明的表达设计思想 克隆代码(写一 ...
- c++中的运算符重载operator2(翁恺c++公开课[31-33]学习笔记)
上一篇operator1中,大概说了下重载的基本用法,接下来对c++中常见的可重载运算符归一下类,说一下它们的返回值,讨论下较为复杂的运算符重载上的坑
- c++中的运算符重载operator1(翁恺c++公开课[30]学习笔记)
运算符重载规则: 只有已经存在的运算符才能被重载,不能自己制造一个c++中没有的运算符进行重载 重载可以在类或枚举类型内进行,也可以是全局函数,但int.float这种已有的类型内是不被允许的 不能二 ...
- static在c\c++中的作用(翁恺c++公开课[28-29]学习笔记)
static相对来说是一个较复杂的修饰符,c++中的static在c的基础之上又包含了static在类中的应用(也就是说多了static的成员变量和static的成员函数):c\c++中静态变量.对象 ...
随机推荐
- UVA 11384 Help is needed for Dexter(递归)
题目链接:https://vjudge.net/problem/UVA-11384 这道题要分析得透: 如果我们手模的话,会发现:如果先将大于$\frac{n}{2}$的数都减去$\frac{n}{2 ...
- 方便的 IcoMoon 图标字体
官网地址:https://icomoon.io/app/#/select 已发现的方便之处: 1.官网已提供大量常用图标字体: 2.可通过 svg 将其转换为 图标字体: 3.不仅可转换,还可自定义编 ...
- Sunday算法浅谈
一.Sunday算法简介 Sunday算法在我看来比起Kmp和bm都更加容易理解,代码实现也更加简洁.Sunday算法由Daniel M.Sunday在1990年提出,它的思想跟BM算法很相似只不过S ...
- Solr 8.2.0最新RCE漏洞复现
漏洞描述 国外安全研究员s00py公开了一个Apache Solr的Velocity模板注入漏洞.该漏洞可以攻击最新版本的Solr. 漏洞编号 无 影响范围 包括但不限于8.2.0(20191031最 ...
- 外置ADC
美信关于如何简化微控制器与温度传感器的接口设计?: 一般外置ADC与单片机UC之间通过SPI或SMBUS接口通信 当IO口比较紧张时可以选择脉冲或频率方波正比与测量值输出的外置ADC,此时也可以实现光 ...
- 【C语言】(for循环嵌套)找出1000以内的水仙花数
什么是水仙花数? 水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153). 分析: 根据定义可知: a*a*a+b*b*b+c*c*c ...
- 洛谷 P3956 棋盘(记忆化搜索)
嗯... 题目链接:https://www.luogu.org/problem/P3956 这是一道比较好搜的题,注意一些剪枝.预处理和魔法的处理问题(回溯). AC代码: #include<c ...
- C语言:判断t所指字符串中的字母是否由连续递增字母组成。-判断一个输入的任何整数n,是否等于某个连续正整数序列之和。-将一副扑克牌编号为1到54,以某种方式洗牌,这种方式是将这副牌分成两半,然后将他们交叉,并始终保持编号1的牌在最上方。
//判断t所指字符串中的字母是否由连续递增字母组成. #include <stdio.h> #include <string.h> void NONO(); int fun( ...
- SSL握手两大加密算法 : RAS算法 和 DH算法解析
写下此博客记录心得体会,如有不足之处请指正 先是手稿笔记 : 正文: 在Https协议中,Client端和Server端需要三个参数才能生成SessionKey来加密信息. 三个参数分别是 ...
- SpringBoot与Shiro整合
一.数据库设计 这里主要涉及到五张表:用户表,角色表(用户所拥有的角色),权限表(角色所涉及到的权限),用户-角色表(用户和角色是多对多的),角色-权限表(角色和权限是多对多的).表结构建立的sq ...