多继承(非虚继承)派生类对象内存结构(基类有虚函数)
2014-08-01 08:18
351 查看
在多继承中(非虚继承),探索一下派生类对象在内存中怎么分布的。
首先定义多继承
输出结果:
对象所占内存大小:20
以4字节为单位,分成5部分:
第0个部分的值0x444080
第1个部分的值0xa
第2个部分的值0x44408c
第3个部分的值0x14
第4个部分的值0x1e
可以看出,第1部分、第3部分、第4部分为类Base1、Base2、Derived中变量a的值。
第0部分和第2部分,看起来像地址,猜想是虚函数表的地址。因为有2个基类Base1和Base2,应该有2个虚函数表。
派生类并没有重新实现虚函数,按照前面的博客,虚函数表中,虚函数地址应该和基类虚函数地址一样,来验证一下
输出结果:
虚函数表1中虚函数地址0x4153c8
虚函数表2中虚函数地址0x415424
基类Base1虚函数的地址0x4153c8
基类Base2虚函数的地址0x415424
可以看出派生类虚函数表1中虚函数地址与基类Base1的虚函数地址相同。
派生类虚函数表2中的虚函数地址与基类Base2的虚函数地址相同。
由此可以得出派生类对象在内存中的结构分布:
可以的出结论:
在派生类的基类中,如果基类有虚函数,那么在派生类中会有对应的虚函数表指针。虚函数表指针的位置与基类中成员变量多少有关。
派生类对象内存分布规则是:(假设基类都有虚函数)
第1基类对应的虚函数表指针
第1基类成员变量
……
第n基类对应的虚函数表指针
第n基类成员变量
派生类自己的成员变量
首先定义多继承
class Base1{ public: Base1():a(10){} virtual void funBase1() { cout<<"This is Base1 Class"<<endl; } int a; }; class Base2{ public: Base2():a(20){} virtual void funBase2() { cout<<"This is Base2 Class"<<endl; } int a; }; class Derived:public Base1,public Base2{ public: Derived():a(30){} /* void funBase1() { cout<<"This is Derived(funBase1) Class"<<endl; } void funBase2() { cout<<"This is Derived(Base2) Class"<<endl; }*/ int a; };通过sizeof查看一下派生类D所占内存为20个字节。把这20个字节的内容,以4个字节为单位输出。
Derived D; cout<<"对象所占内存大小:"<<sizeof(D)<<endl; int **p=(int **)&D; cout<<"以4字节为单位,分成5部分:"<<endl; for(int i=0; i<5; i++) cout<<"第"<<i<<"个部分的值"<<p[i]<<endl;
输出结果:
对象所占内存大小:20
以4字节为单位,分成5部分:
第0个部分的值0x444080
第1个部分的值0xa
第2个部分的值0x44408c
第3个部分的值0x14
第4个部分的值0x1e
可以看出,第1部分、第3部分、第4部分为类Base1、Base2、Derived中变量a的值。
第0部分和第2部分,看起来像地址,猜想是虚函数表的地址。因为有2个基类Base1和Base2,应该有2个虚函数表。
派生类并没有重新实现虚函数,按照前面的博客,虚函数表中,虚函数地址应该和基类虚函数地址一样,来验证一下
Derived D; Base1 B1; Base2 B2; int **p=(int **)&D; cout<<"虚函数表1中虚函数地址0x"<<hex<<p[0][0]<<endl;//对应第0部分 cout<<"虚函数表2中虚函数地址0x"<<hex<<p[2][0]<<endl;//对应第1部分 p=(int **)&B1; cout<<"基类Base1虚函数的地址0x"<<hex<<p[0][0]<<endl; p=(int **)&B2; cout<<"基类Base2虚函数的地址0x"<<hex<<p[0][0]<<endl;
输出结果:
虚函数表1中虚函数地址0x4153c8
虚函数表2中虚函数地址0x415424
基类Base1虚函数的地址0x4153c8
基类Base2虚函数的地址0x415424
可以看出派生类虚函数表1中虚函数地址与基类Base1的虚函数地址相同。
派生类虚函数表2中的虚函数地址与基类Base2的虚函数地址相同。
由此可以得出派生类对象在内存中的结构分布:
可以的出结论:
在派生类的基类中,如果基类有虚函数,那么在派生类中会有对应的虚函数表指针。虚函数表指针的位置与基类中成员变量多少有关。
派生类对象内存分布规则是:(假设基类都有虚函数)
第1基类对应的虚函数表指针
第1基类成员变量
……
第n基类对应的虚函数表指针
第n基类成员变量
派生类自己的成员变量
相关文章推荐
- 虚函数: 多重继承下派生类对象的内存结构
- 多态继承情况下,有一个基类指针指向派生类对象,如何用它调用基类的虚函数?
- C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中
- 面向对象--多继承&派生类对象内存布局分析&各基类指针所指向的位置分析
- 面向对象--多继承&派生类对象内存布局分析&各基类指针所指向的位置分析
- 多继承(虚继承)派生类对象内存结构
- 面向对象--多继承&派生类对象内存布局分析&各基类指针所指向的位置分析(解决面试宝典第四版P147问题)
- 指向派生类对象的基类指针与虚函数
- 【提问整理】protected继承,派生类对象如何访问基类成员?
- 使用派生类对象通过成员函数指针调用基类虚函数之不可能性的证明
- C++继承、多重继承与虚基类 继承、多重继承时对象内存分布
- C++对象内存布局--⑧GCC编译器--虚拟继承多个基类
- 虚表结构与虚继承内存对象模型(gcc vs vc)
- 派生类是否继承基类中的private成员,若继承为何不能在成员函数中访问?
- 三十二、C++内存布局,对象大小计算、虚函数虚继承对类内存模型的影响
- C++虚函数的陷阱--派生类对象的基类函数调用基类虚函数出错
- 虚表结构与虚继承内存对象模型
- 再谈带有虚函数的类对象之内存结构
- 派生类对象成员函数与基类成员函数的重载
- 虚表结构与虚继承内存对象模型