C++对象内存模型2 (虚函数,虚指针,虚函数表)
2016-09-07 20:32
381 查看
从例子入手,考察如下带有虚函数的类的对象内存模型:
注:在子类中出现与父类相同名称的变量和非虚函数不是最佳实践,这里是为了说明其内存结构。
其对象内存结构见下图。
*图片来源于侯捷老师
对其分析如下:
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表示对应的函数在第几个位置(编译器在建立虚函数表的时候已知),从而实现动态绑定。
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++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- 虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图 .
- 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
- C++虚函数、虚继承、对象内存模型
- C++对象内存模型(高级)—多重继承与虚函数表(转)
- [置顶] 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- Data语意学之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- [置顶] 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- C++虚函数、虚继承、对象内存模型(转)
- C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- C++对象模型笔记:对象的三种内存布局
- C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中
- [C++对象模型][4]指针与字符串
- C++对象内存布局--②测试派生类跟基类的虚函数表
- [C++对象模型][6]sizeof与对象内存布局