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. Foundation Sorting: Single List Insertion Sort

    /* List Insertion Sorting. * Implementation history:. * 2013-09-15, Mars Fu, first version. */ #incl ...

  2. SQL Server:错误处理及事务控制

    目录: 解读错误信息 RAISERROR THROW 实例 使用 @@ERROR 使用 XACT_ABORT 使用TRY/CATCH 现实中的事务语句 删除 更新 银行取钱 解读错误信息 Msg 54 ...

  3. runtime的概念,message send如果寻找不到相应的对象,如何进行后续处理

    运行时刻是指一个程序在运行(或者在被执行)的状态.也就是说,当你打开一个程序使它在电脑上运行的时候,那个程序就是处于运行时刻.在一些编程语言中,把某些可以重用的程序或者实例打包或者重建成为“运行库”. ...

  4. UIButton 动态改变文本闪烁问题

    当动态改变(比如一秒改变一次)按钮的Title的时候发现按钮每次都要闪烁一下:解决方法如下: self.settleButton.titleLabel.text = title; [self.sett ...

  5. CodeForce 569A

    Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u   Description Litt ...

  6. JavaSE学习总结第14天_API常用对象4

      14.01 如何校验一个QQ号码案例 import java.util.Scanner; /* * 校验qq号码. * 1:要求必须是5-15位数字 * 2:0不能开头 * * 分析: * A:键 ...

  7. Android 开发技巧

    1, ActionBar.setTitle() 的参数是 CharSequence,可以用SpannableString的,颜色字形随你

  8. 运行PHP

    /usr/local/php/bin/php /home/www/index.php

  9. [LeetCode]题解(python):020-Valid Parentheses

    题目来源: https://leetcode.com/problems/valid-parentheses/ 题意分析: 这道题输入一段只包括括号的字符串,判断这个字符串是否已经配对.配对的规则是,每 ...

  10. (IOS)N duplicate symbols for architecture i386

    Xcode编译时的error,出现此情况的汇总引用如下: 1.可能存在两个main入口: 2.导入的.h文件可能误写为.m: 3.两文件间可能存在重复定义的全局变量名: 4.使用#include导入文 ...