多态 : 顾名思义,多态就是多种形态,也就是对不同对象发送同一个消息,不同对象会做出不同的响应。

并且多态分为静态多态和动态多态。

静态多态就是在系统编译期间就可以确定程序执行到这里将要执行哪个函数,例如:函数的重载,对象名加点操作符执行成员函数等,都是静态多态,其中,重载是在形成符号表的时候,对函数名做了区分,从而确定了程序执行到这里将要执行哪个函数,对象名加点操作符执行成员函数是通过this指针来调用的。

函数的重载比较简单,不再赘述,这里我们通过一个简单的例子来看一下对象名加点操作符执行成员函数的静态多态:

class A
{
public:void Set(int a){_a = a;}
public:int _a;
};int main()
{A a1;a1.Set(15);return 0;
}

这里定义了一个A类,有一个成员函数和一个成员,我们将程序的部分汇编代码截取出来如下图:

我们可以看到这里直接是一个lea指令将a1对象的地址放入寄存器eax中,也就是对象的this指针,然后用call指令就可以跳转到Set函数,也就是说其汇编代码在此时就知道应该要去到哪个地方之行哪个函数,这就是静态多态,也叫编译时多态

动态多态则是利用虚函数实现了运行时的多态,也就是说在系统编译的时候并不知道程序将要调用哪一个函数,只有在运行到这里的时候才能确定接下来会跳转到哪一个函数的栈帧。

在说动态多态之前我们先来看一下什么是虚函数,虚函数就是在基类中声明该函数是虚拟的(在函数之前加virtual关键字),然后在子类中正式的定义(子类中的该函数的函数名,返回值,函数参数个数,参数类型,全都与基类的所声明的虚函数相同,此时才能称为重写,才符合虚函数,否则就是函数的重载),再定义一个指向基类对象的指针,然后使该指针指向由该基类派生的子类对象,再然后用这个指针来调用改虚函数,就能实现动态多态。

下面我们通过一个例子来看一下利用虚函数实现的动态多态:

class A
{
public:A(int a = 10):_a(a){}virtual void Get(){cout << "A:: _a=" << _a << endl;}
public:int _a;
};class B :  public A
{
public:B(int b = 20):_b(b){}void Get(){cout << "B:: _b=" << _b << endl;}int _b;
};int main()
{A a1;B b1;A* ptr1 = &a1;ptr1->Get();ptr1 = &b1;ptr1->Get();return 0;
}

在这里我们看到,基类A的Get函数声明为虚函数,在B类中进行了重写,
然后在main函数中分别用基类的ptr1和指向子类的ptr2进行调用虚函数Get,我们得到了如下图的输出:

这说明确实是实现了不同调用,而且是在运行时,那么虚函数的底层到底是怎么实现的呢,我们来看一下汇编代码及其对象模型

通过上图的汇编代码,我们看到这里做了一系列的指针解引用处理,最后确定了eax中应该存放的this指针的值,要搞清楚这个必须要搞清楚子类的对象模型。

用监视窗口查看b1可以看到如上图所示,这里的_vfptr是一个虚表指针,它指向一个存放该类对象的所有虚函数的地址的表,我们可以将该表理解为一个函数指针数组,在该数组的最后一个元素,编译系统会将其置为0,。
对象模型如下图示:

其中红色为A类的成员,黑色为B类对象b1的成员,紫色就是一个虚函数表,存放着存放该类对象的所有虚函数的地址,汇编代码做了一系列的指针解引用处理就是为了从虚函数表中找到相应的虚函数进行调用,从而实现了动态多态。

C++多态——静态多态与动态多态相关推荐

  1. [转载] 【Python进阶】4-2 多态 | 什么是多态 / 静态语言vs动态语言 / python中多态

    参考链接: Python中的多态 文章目录 1.什么是多态"开闭"原则 2.静态语言 vs 动态语言小结 3.python中多态 1.什么是多态 要理解什么是多态,我们首先要对数据 ...

  2. C++知识点 多态、静态多态、动态多态

    多态 有了继承才有多态的概念,首先说一下继承. 继承的概念是派生类可以调用基类的成员.常举的例子,动物是基类,它拥有所有动物共有的一些特征和方法.它会衍生出猫的类,狗的类,派生出的类除了有动物公共的特 ...

  3. 【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用父类方法 | 静态多态 | 动态多态 | 虚函数 | 纯虚函数 )

    文章目录 类的继承 方法的重写 子类中调用父类方法 多态 虚函数 虚函数示例 纯虚函数 相关代码 类的继承 1. 继承表示 : C++ 中继承可以使用 ":" 符号 , 格式为 & ...

  4. C++静态多态与动态多态

    静态多态(编译期/早绑定) 函数重载 class A {public:void do(int a);void do(int a, int b); }; 动态多态(运行期期/晚绑定) •虚函数:用 vi ...

  5. C++_类和对象_C++多态_多态的基本语法_静态多态_动态多态_虚函数---C++语言工作笔记069

    然后我们再来看看C++中的多态,这里还要注意一点,就是在C++中是可以用多继承的, 但是java.不行,只能实现多个接口,不能继承多个类.这让c++会更加灵活一点. 可以看到,上面说了,在c++中,分 ...

  6. Java静态多态和动态多态

    方法解析 Class文件的编译过程中不包含传统编译中的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址.这个特性给Java带来了更强大的动态扩 ...

  7. 动态多态和静态多态(C++)

    多态:即一个接口多种实现方式:C++中的多态分为两种:静态多态与动态多态 一.静态多态:也成为编译时的多态:在编译时期就已经确定要执行了的函数地址了:主要有函数重载和函数模板(这里只写函数重载) (1 ...

  8. C++ 多态(动态多态)

    本文结合黑马程序员.C语言中文网以及<C++ Primer>对多态进行了总结 多态的基本概念 多态是C++面向对象三大特性之一. 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态 ...

  9. 【C++】动态多态与虚函数

    文章目录 一.动态多态概念 二.虚函数 2.1 虚函数的概念 2.2 虚函数的特点 三.动态多态实现的背后编译器帮我做了什么? 四.虚析构 4.1 解决多态中资源释放的问题 4.2 解决多重继承中的资 ...

最新文章

  1. 手动部署OpenStack环境(二:CentOS6.6虚拟机的安装及配置)
  2. 斯坦福大学「黑盒学习」研究:使用神经变分推理的无向图模型,可替代「采样」 | 附NIPS 2017论文
  3. [实变函数]4.2 Egrov 定理
  4. 数据结构与算法 / 红黑树
  5. python中的seed_Python seed() 函数 - Python 教程 - 自强学堂
  6. 如何生成 Flink 作业的交互式火焰图?
  7. 反射矩阵(reflection matrix)推导
  8. CSS3 变换/变形(transform)
  9. sql在insert的同时把某个字段返回来_项目实践:后端接口统一规范的同时,如何优雅得扩展规范?...
  10. [Java] 蓝桥杯ALGO-78 算法训练 确定元音字母位置
  11. 别怕,“卷积“其实很简单
  12. 静态代码块与构造函数的作用
  13. [雪峰磁针石博客]软件测试专家工具包2性能测试
  14. 数据解读 | 川菜出圈只靠辣?你太小瞧川菜了
  15. iexplore.exe命令行参数解释
  16. linux中的各文件的颜色含义
  17. 服务器怎么连接无线路由器怎么设置,光猫连接无线路由器怎么设置
  18. VMware导致电脑蓝屏解决方案
  19. 暗月渗透实战靶场-项目七(上)
  20. 基于javaweb的在线点餐+外卖配送系统

热门文章

  1. VMware中linux环境下oracle安装图文教程(一)
  2. 一个软件项目团队的分工
  3. MapStruct、ignore
  4. 程序员2019可以看的书单
  5. tar.gz文件命名及压缩解压方法
  6. android 安装第三方应用,Android手机常识 第三方应用如何安装
  7. 线搜索(line search)方法
  8. ssh-agent 详解
  9. cloudflare免费证书_使用百度云加速免费加速你的博客
  10. 雨天在火车站台上撑伞会触电吗?