C++学习之多态的实现

原创 2016年05月30日 22:56:00

多态又分为静态多态和动态多态。

静态多态其实就是函数重载,动态多态就是一般我们所说的多态。

多态作为面向对象的三大特征之一,需要另外两大特征:封装、继承的支持。

本文主要讲讲,我看了一点《深度探索C++模型》总结多态是怎样实现的。

1.C++内存布局

C++对象主要可以有如下几种成员:

(1)数据成员

①static数据成员

②nonstatic数据成员

(2)函数成员

①static函数成员

②nonstatic函数成员

③virtual函数成员


其中,nonstatic数据成员和virtual函数成员是要占用,变量的内存空间的。

其他成员都是使用一个公共的静态区域。

具体地讲,每一个类对象会为其每一个nonstatic数据成员持有一个指针,而对于其所有的虚函数,会持有1个指针vptr,这个指针指向一个表vtbl,这个表里每一个位置也是一个指针,指向该类的各个虚函数。


2.多态的实现

在定义父类和子类的时候,父类对象的与子类对象都拥有vptr这个成员,但是父类的vptr指向的vtbl里面的指针指向的虚函数是父类的版本。

子类的vptr指向的btbl里面的指针指向的虚函数是子类的版本。

这个vptr指向的btbl里面放的虚函数是哪一个版本是由构造器、拷贝复制运算符决定的。

如果是构造一个父类对象,就是指向父类的虚函数,如果构造一个子类对象就是指向一个子类的虚函数。

如果把一个子类对象,强制转换为一个父类对象,其vptr也会变为指向父类虚函数的。


但是当我们把一个父类的指针赋值一个指向了子类的指针,这个时候首先会发生切割,将子类多出来的成员给切割掉。

因为不同类型的指针,会限定从该地址开始的后面的范围的内存布局。

但是由于指针赋值,并没有调用子类或者父类的构造器,并且vptr是子类对象与父类对象所共有的,所以并没有被切割。

所以这个时候如果一个指针开始指向了一个子类对象,现在通过这个指针调用的虚函数版本就是子类的,虽然这个指针现在是一个父类指针。


注意:

2016/06/01更新

我用G++ 4.9.2编译器验证出来的一些信息

1.vtbl源自父类的会不会也用来填装子类新加入的虚函数
会。
如果父类没有虚函数,子类有就会在子类额外区间多一个vptr
如果父类有虚函数,父类区间的vptr指向的vtbl也会存放子类新建的虚函数。


2.vtbl会不会同时用来记录虚基类信息
不会。有一个vptr,有一个vbtr
但是如果虚基类里面没有数据成员的话,是不会产生一个vbtr用于访问数据成员的。


3.如果是多重继承的虚拟基类是采用多少个vbtr
多重继承了多少个虚拟基类就会有多少个vbtr


4.如果是多阶继承
对于一阶,如果有单独定义的变量,那么每一阶就会产生一个vbtr


总结:
GCC的这些貌似少了很多优化,但是它好像是讲vptr和vbtr都用一个指针来实现的,然后进行了相应地处理。

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++学习之多态篇(异常处理)

一、异常处理 概念:对有可能发生异常的地方做出预见性的安排,异常处理过程如下图所示: f1()出现异常,就会抛给调用者f2(),如果f2()处理不了就继续往上抛给它的调用者,依次类推。。。 2...
  • hudfang
  • hudfang
  • 2016年02月03日 15:28
  • 480

C++ 多态 以及实现多态的三种方式

实实在在说多态(C++篇) 1.    什么是多态... 1 2.    多态带来的好处... 1 3.    C++中实现多态的方式... 1 4.    细说用函数重载实现的多...
  • lq296263775
  • lq296263775
  • 2014年09月02日 21:59
  • 763

C++多态的实现方式总结

实现多态有两种方法: 1、覆盖 *********** 覆盖是指子类重新定义父类的虚函数的做法。 2、重载 *********** 重载是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数...
  • sinat_20265495
  • sinat_20265495
  • 2015年11月30日 14:45
  • 2812

C++多态的实现及原理详细解析

C++多态的实现及原理详细解析
  • Li_Ning_
  • Li_Ning_
  • 2016年07月10日 17:19
  • 2432

C++多态技术的实现和反思

作者:杨喜敏 孟岩  面向对象技术最早出现于1960年代的Simula 67系统,并且在1970年代保罗阿托实验室开发的Smalltalk系统中发展成熟。然而对于大部分程序员来说,C++是第一个可...
  • zhouguoqionghai
  • zhouguoqionghai
  • 2015年12月11日 16:24
  • 2791

C语言模式实现C++继承和多态

这个问题主要考察的是C和C++的区别,以及C++中继承和多态的概念。C和C++的区别C语言是面向过程的语言,而C++是面向对象的过程。什么是面向对象和面向过程? 面向过程就是分析解决问题的步骤,然后用...
  • wenqiang1208
  • wenqiang1208
  • 2017年07月28日 12:36
  • 666

C++中引用(&)的用法和应用实例===引用和多态的关系!!!!!!!!!!!!!!!!!

http://www.cnblogs.com/Mr-xu/archive/2012/08/07/2626973.html C++中引用(&)的用法和应用实例 对...
  • wangyin159
  • wangyin159
  • 2015年08月29日 19:34
  • 1786

C++多态,虚函数作用及底层实现原理

简述C++虚函数作用及底层实现原理 1.forewordC++是面向对象程序设计,其包括3项特点: (1)数据抽象:接口和实现分离 (2)继承:父类和子类 (3)多态:动态绑定本文讨论多态。当父...
  • niaolianjiulin
  • niaolianjiulin
  • 2017年07月31日 21:18
  • 171

C++多态和虚表(详细)

多态的这个概念稍微有点模糊,如果想在一开始就想用清晰用语言描述它,让读者能够明白,似乎不太现实,所以我们先看如下代码: //例程1 #include using namespace s...
  • hacker00011000
  • hacker00011000
  • 2015年10月25日 16:08
  • 604

C++ 多态 指针转换

class A{ public: A(); virtual ~A();};class B{ public: B(); virtual ~B();};class C : public A...
  • CNHK1225
  • CNHK1225
  • 2015年10月21日 16:03
  • 716
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++学习之多态的实现
举报原因:
原因补充:

(最多只允许输入30个字)