C++的多态性是通过动态绑定实现的

  • 非虚函数是在编译时绑定的;
  • 通过对象进行的函数(虚函数,非虚函数)也是编译时绑定的;

C++编译器在编译的时候,要确定每个对象调用的函数(要求此函数是非虚函数)的地址,这称为早期绑定(early binding)

  • 当且仅当通过指针或引用调用虚函数时,动态绑定

动态绑定又叫运行时绑定(run time binding)。

example:

class animal{
public:
void sleep(){ cout<<"animal sleep"<<endl; }
void breathe(){ cout<<"animal breathe"<<endl; }
}; class fish:public animal{
public:
void breathe(){ cout<<"fish bubble"<<endl; }
}; int main(){
fish fh;
animal *pAn=&fh; // 隐式类型转换
pAn->breathe(); // 运行结果: animal breathe
return 0;
}

因为编译器在编译的时候,就已经确定了对象调用的函数的地址

pAn->breathe()的函数地址为animal::breathe()的地址。

动态绑定

要解决这个问题就要使用动态绑定技术(有的地方叫迟绑定(late binding)技术)。(c++是静态绑定语言,一些动态绑定语言 如java ,python)

C++的多态性用一句话概括就是:

  1. 在基类的函数前加上virtual关键字,
  2. 在派生类中重写该函数,
  3. 运行时将会根据对象的实际类型来调用相应的函数。

编译器在编译的时候,发现animal类中有虚函数,此时编译器会为每个包含虚函数的类创建一个虚表(即vtable),

该表是一个一维数组,在这个数组 中存放每个虚函数的地址。

对于例例子,animal和fish类都包含了一个虚函数breathe(),因此编译器会为这两个类都建立一个虚表。

那么如何定位虚表呢?

编译器另外还为每个类的对象提供了一个虚函数表指针(即vptr),这个指针指向了对象所属类的虚函数表。

在程序运行时,根据对象的类型初始化vptr,从而让vptr正确的指向所属类的虚表,从而在调用虚函数时,就能够找到正确的函数。


简而言之,多态性是一个接口多种实现。

C++多态原理的更多相关文章

  1. 多态原理探究-从C++编译器角度理解多态的实现原理

    理论知识: 当类中声明虚函数时,编译器会在类中生成一个虚函数表. 虚函数表是一个存储类成员函数指针的数据结构. 虚函数表是由编译器自动生成与维护的. virtual成员函数会被编译器放入虚函数表中. ...

  2. 深入理解JAVA多态原理

    之前一直知道多态是什么东西,平时敲代码也经常用到多态,但一直没有真正了解多态底层的运行机制到底是怎么样的,这两天才研究明白点,特地写下来,跟各位同学一起进步,同时也希望各位大神指导和指正. 多态的概念 ...

  3. C++虚函数实现多态原理(转载)

    一.前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态 ...

  4. 【转】深入理解Java多态原理

    之前一直知道多态是什么东西,平时敲代码也经常用到多态,但一直没有真正了解多态底层的运行机制到底是怎么样的,这两天才研究明白点,特地写下来,跟各位同学一起进步,同时也希望各位大神指导和指正. 多态的概念 ...

  5. C++多态及其实现原理

    1.    多态的定义:多态含义为一个事物有多种形态.在C ++程序设计中,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数,主要分为静态多态和动态多态: 静态 ...

  6. 深入剖析C++多态、VPTR指针、虚函数表

    在讲多态之前,我们先来说说关于多态的一个基石------类型兼容性原则. 一.背景知识 1.类型兼容性原则 类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代.通过公有继承,派 ...

  7. 第32节:Java中-构造函数,静态方法,继承,封装,多态,包

    构造函数实例 class Cat{ // 设置私有的属性 name private String name; // 设置name的方法 public void setName(String Name) ...

  8. 第二十九节:Java基础知识-类,多态,Object,数组和字符串

    前言 Java基础知识-类,多态,Object,数组和字符串,回顾,继承,类的多态性,多态,向上转型和向下转型,Object,数组,多维数组,字符串,字符串比较. 回顾 类的定义格式: [类的修饰符] ...

  9. Java面向对象的基本概念(对象、封装、继承、多态、抽象、接口、泛型)

    对象:是一个自包含的实体,用一组可识别的特征和行为来标识. 类:具有相同的属性和功能的对象的抽象合集.(类关键字class,首字母大写). 实例:就是一个真实的对象. 实例化:创建对象的过程,关键字是 ...

随机推荐

  1. QT在ui文件上建立信号操机制会不会对后期维护产生影响 - love4Mario的专栏 - 博客频道 - CSDN.NETQT在ui文件上建立信号操机制会不会对后期维护产生影响 - love4Mario的专栏 - 博客频道 - CSDN.NET

    QT在ui文件上建立信号操机制会不会对后期维护产生影响 - love4Mario的专栏 - 博客频道 - CSDN.NET QT在ui文件上建立信号操机制会不会对后期维护产生影响 分类: 学习心得 2 ...

  2. hpu校赛--雪人的高度(离散化线段树)

    1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec  内存限制: 128 MB 提交: 81  解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...

  3. [置顶] WEBSOKET服务器搭建

    简单介绍一下tomcat的webSocketAPI使用: 在这里啰嗦几句:[ 很多朋友听说webSocket不知道是什么.知道是什么不知道怎么用,知道怎么用不知道具体实现.其实我当初也是这样. 实际上 ...

  4. Android的电源管理框架

    Android的电源管理框架 Android通过锁和定时器来切换系统的状态,使系统的功耗降至最低,整个系统的电源管理框架分成五个部分:应用层,framework层,JNI层,HAL层和内核层.电源管理 ...

  5. LINQ 图解

    LINQ 图解 原创地址:http://www.cnblogs.com/jfzhu/archive/2013/01/01/2841332.html 转载请注明出处 LINQ,语言集成查询(Langua ...

  6. Redis初始化配置及增删改查

    package com.calc.tools import redis.clients.jedis.JedisPool import redis.clients.jedis.Jedis import ...

  7. Linux网卡设置

    http://blog.chinaunix.net/uid-20149676-id-1733254.html

  8. 解题报告 HDU1176 免费馅饼

    免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. CodeForces - 27E--Number With The Given Amount Of Divisors(反素数)

    CodeForces - 27E Number With The Given Amount Of Divisors Submit Status Description Given the number ...

  10. 一行JavaScript代码获取页面中的所有超链接地址

    因为我喜欢收集Web开发类的网址,平时对网址就很敏感. 我总结了一下我收集网址的几个阶段: 1.纯手工阶段,傻傻的阶段. 在这个阶段,主要是收集一些在页面中展现出来的网址,就是说,如果网址出现在HTM ...