C++对象内存模型2 (虚函数,虚指针,虚函数表)(转)
class A {
public:
virtual void vfunc1();
virtual void vfunc2();
void func1();
void func2();
virtual ~A();
private:
int m_data1, m_data2;
};
class B : A {
public:
virtual void vfunc1();;
void func2();
virtual ~B();
private:
int m_data3;
};
class C : B {
public:
virtual void vfunc1();
void func();
private:
int m_data1, m_data4;
};
注:在子类中出现与父类相同名称的变量和非虚函数不是最佳实践,这里是为了说明其内存结构。

对其分析如下:
1. 每个含有虚函数的类在内存中多一根指针(vptr),见图中a,b,c对象中第一个位置,存储的是虚函数表(vtbl)所在的位置。
2. 虚函数表(vtbl)存储着所有虚函数的位置(地址),由于其动态绑定特性,在覆写(override)后在子类中存储的虚函数位置与父类中不相同。
3. 分析上述代码, B继承A,所以A中的数据部分也被B继承下来,同时B添加上了自己的数据部分m_data3,加之vptr,组成了B左侧的内存布局。
A中的虚函数vfunc1(),vfunc2()可以被覆写和动态绑定。
所以在B中,vfunc1()被覆写,其vtbl中对应项指向了新的函数的位置(亮蓝色)。vfunc2()未被覆写,仍然指向原先位置(深蓝色)。
C与B同理,vfunc1()被覆写,其vtbl中对应项指向了新的函数的位置(橘黄色)。vfunc2()未被覆写,仍然指向原先位置(深蓝色)。
非虚函数静态绑定,存储在单独的内存空间(code memory section,灰色函数部分),调用时把对象的this指针,传给一个invisible参数,以便确定谁在调用函数。
4. 调用虚函数的语句的C语言形式如图中下部分所示,其中n表示对应的函数在第几个位置(编译器在建立虚函数表的时候已知),从而实现动态绑定。
C++对象内存模型2 (虚函数,虚指针,虚函数表)(转)的更多相关文章
- C++对象内存模型2 (虚函数,虚指针,虚函数表)
从例子入手,考察如下带有虚函数的类的对象内存模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1 ...
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- 对C++对象内存模型造成的影响(类/对象的大小)
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- c++ 虚函数和纯虚函数
在你设计一个基类的时候,如果发现一个函数需要在派生类里有不同的表现,那么它就应该是虚的.从设计的角度讲,出现在基类中的虚函数是接口,出现在派生类中的虚函数是接口的具体实现.通过这样的方法,就可以将对象 ...
- C++ - 虚基类、虚函数与纯虚函数
虚基类 在说明其作用前先看一段代码 class A{public: int iValue;}; class B:public A{public: void bPrintf(){ ...
- c++中虚函数和纯虚函数定义
只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声 ...
- C++ 虚函数 、纯虚函数、接口的实用方法和意义
也许之前我很少写代码,更很少写面向对象的代码,即使有写多半也很容易写回到面向过程的老路上去.在写面向过程的代码的时候,根本不管什么函数重载和覆盖,想到要什么功能就变得法子的换个函数名字,心里想想:反正 ...
- C++多态、虚函数、纯虚函数、抽象类、虚基类
一.C++多态 C++的多态包括静态多态和动态多态.静态多态包括函数重载和泛型编程,动态多态包括虚函数.静态多态是指在编译期间就可以确定,动态多态是指在程序运行时才能确定. 二.虚函数 1.虚函数为类 ...
- 【转】C++ 虚函数&纯虚函数&抽象类&接口&虚基类
1. 动态多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数. 多态性就是允许将子类类型的指针赋值给父类类型 ...
- C++(九)— 虚函数、纯虚函数、虚析构函数
1.虚函数 原因:通过指针调用成员函数时,只能访问到基类的同名成员函数.在同名覆盖现象中,通过某个类的对象(指针及引用)调用同名函数,编译器会将该调用静态联编到该类的同名函数,也就是说,通过基类对象指 ...
随机推荐
- Sitecore客户体验成熟度模型之旅
“成熟”这个词带来了很多想法:你在青年时不愿意找到工作?你四岁的孩子偶尔发脾气?可能还有你的公司能否在数字化时代提供个性化的客户体验? 你如何定义CX成熟度?如果您的CX战略仍处于开发阶段,您需要达到 ...
- MOOC Web前端笔记(三):CSS样式
CSS样式 CSS概述 CSS--Cascading Style Shees层叠样式表 HTML定义网页的内容,CSS定义内容的样式. 内容和样式相互分离,便于修改样式. CSS语法 p{ font- ...
- Maven distributionManagement 分发构件至远程仓库
https://blog.csdn.net/qq827245563/article/details/82661583 maven发布到本地仓库,和私服https://blog.csdn.net/u01 ...
- 8、VUE自定义组件
1.为什么要使用自定义组件? 自定义组件是用来封装复杂的内容,提高可重用性,比如封装复杂的表格组件.日历组件.图片轮播组件等. 2.自定义组件 2.1. 全局组件 全局组件是每个Vue对象都能使用的组 ...
- 推荐算法之E&E
一.定义 E&E就是探索(explore)和利用(exploit). Exploit:基于已知最好策略,开发利用已知具有较高回报的item(贪婪.短期回报),对于推荐来讲就是用户已经发现的兴趣 ...
- 无法打开内核设备:\\Global\\vmx86
关于如题目的问题,网上有好几个解决办法,这里只介绍最方便的一个办法,利用脚本来解决 @Echo Off title Hankcs's program color 8F CD %~d0 CD %~dp0 ...
- 剑指Offer 总结
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. public class Solution { public ListNode EntryNodeOfLoop(ListNo ...
- 2019 第一视频java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.第一视频等公司offer,岗位是Java后端开发,因为发展原因最终选择去了第一视频,入职一年时间了,也成为了面 ...
- loj#10078. 新年好(最短路)
题目: loj#10078. 新年好 解析: 亲戚只有五个,可以把它们看成2,3,4,5,6号点,分别跑最短路,记录一下距离,然后DFS一下 这题非常玄学,我开了一个\(12*12\)的数组,没有离散 ...
- Matlab访问者模式
访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式.它 ...