码迷,mamicode.com
首页 > 编程语言 > 详细

c++ 之 内存模型:虚函数篇

时间:2019-08-26 00:26:16      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:基于   部分   继承   自己   需要   virt   通过   nbsp   面向   

一、虚函数

1.虚函数表位置分析

    类:有虚函数,这个类会产生一个虚函数表

    类的对象:有一个指针(vptr)会指向类的虚函数表——虚函数表指针。(位置可能在类内存空间的开头,也可能在末尾,具体由编译器实现决定)

 

2.继承关系作用下虚函数的手工调用

    拿到虚函数表的地址,通过定义函数指针并赋值的方式可以直接调用虚函数。子类的虚函数会覆盖父类的虚函数。

 

3.虚函数表分析

    (1)一个类只有包含虚函数才会存在虚函数表,同属于一个类的对象共享虚函数表,但拥有各自的虚函数表指针(vptr)。当然所有的该类对象的vptr都指向同一个虚函数表。

    (2)父类中有虚函数就等于子类中有虚函数。(父类中有虚函数表则子类中肯定有虚函数表) 因为子类会继承父类。

         如果子类中将父类虚函数的virtual去掉,函数就不再是虚函数?

         在父类中是虚函数,即使子类中该函数不写virtual,它依然是虚函数。

         不管是父类还是子类,每一个类都只有属于自己的唯一虚函数表。子类中是否会存在多个虚函数表?

    (3)如果子类中完全没有新的虚函数,则子类虚函数表的内容与父类虚函数表的内容相同。但两个虚函数表在内存中的位置是不同的。是两个虚函数表。虚函数表中的每一项包含一个虚函数的首地址,但如果子类的虚函数表某项和父类虚函数表某项代表同一个函数(这表示子类没有覆盖父类的虚函数)则该表项所指向的函数相同。

    (4)超出虚函数表部分内容不可知。

    (5)当子类对象为父类对象赋值时,子类中的属于父类的那一部分会被编译器自动区分(切割)出来并拷贝给父类对象;所以BaseClass base = derive;实际做了两件事:一、生成了一个base对象;二、用derive的部分值来对base对象进行了初始化。 (但此时编译器在处理base对象的虚函数表指针 值的时候,编译器会根据base的类型来自动决策为BaseClass 的虚函数表地址)

    (4)OO(面向对象)和OB(基于对象)概念

      C++是通过类的指针和引用来支持多态,这是一种程序设计风格,这就是我们常说的面向对象。object-oriented model

      OB(object-base)也叫ADT抽象数据模型[abstract datatype model],不支持多态,执行速度更快。因为函数调用的解析不需要运行时决定(没有多态),比如Base *pbase = new Derive();Base &base2 = derive2;而是在编译期间完成,内存空间紧凑程度上更为紧凑,因为没有虚函数这些概念。

      但OB(object-base)的设计灵活性上较差,C++既支持面向对象程序设计。也支持基于对象程序设计。

 

4.多重继承虚函数表分析

 

c++ 之 内存模型:虚函数篇

标签:基于   部分   继承   自己   需要   virt   通过   nbsp   面向   

原文地址:https://www.cnblogs.com/sxgloverr1314/p/11410039.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!