C++对象内存布局-多重继承
来源:互联网 发布:pb数据窗口列标题修改 编辑:程序博客网 时间:2024/06/17 05:51
看《深度探索C++对象模型》有点力不从心。
找到了一篇博客写的很好,把代码跑了一篇,加深了理解
原博客:http://blog.csdn.net/haoel/article/details/3081328
内存分布规则:
- 每个父类都有自己的虚表。
- 子类的成员函数被放到了第一个父类的表中。
- 内存布局中,其父类布局依次按声明顺序排列。
- 每个父类的虚表中的f()函数都被overwrite成了子类的f()。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。
来看实例:
假设有下面这样一个类的继承关系。注意:子类只重载了父类的f()函数,而还有一个是自己的函数(我们这样做的目的是为了用g1()作为一个标记来标明子类的虚函数表)。而且每个类中都有一个自己的成员变量:
代码:
#include<iostream>using namespace std;class Base1 {public: int ibase1; Base1() :ibase1(10) {} virtual void f() { cout << "Base1::f()" << endl; } virtual void g() { cout << "Base1::g()" << endl; } virtual void h() { cout << "Base1::h()" << endl; }};class Base2 {public: int ibase2; Base2() :ibase2(20) {} virtual void f() { cout << "Base2::f()" << endl; } virtual void g() { cout << "Base2::g()" << endl; } virtual void h() { cout << "Base2::h()" << endl; }};class Base3 {public: int ibase3; Base3() :ibase3(30) {} virtual void f() { cout << "Base3::f()" << endl; } virtual void g() { cout << "Base3::g()" << endl; } virtual void h() { cout << "Base3::h()" << endl; }};class Derive : public Base1, public Base2, public Base3 {public: int iderive; Derive() :iderive(100) {} virtual void f() { cout << "Derive::f()" << endl; } virtual void g1() { cout << "Derive::g1()" << endl; }};int main(){ typedef void(*Fun)(void); Fun pFun; Derive d; int** pVtab = (int**)&d; cout << "[0] Base1::_vptr->" << endl; pFun = (Fun)pVtab[0][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[0][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[0][2]; cout << " [2] "; pFun(); pFun = (Fun)pVtab[0][3]; cout << " [3] "; pFun(); pFun = (Fun)pVtab[0][4]; cout << " [4] "; cout << pFun << endl; cout << "[1] Base1.ibase1 = " << (int)pVtab[1] << endl; int s = sizeof(Base1) / 4; cout << "[" << s << "] Base2::_vptr->" << endl; pFun = (Fun)pVtab[s][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[s][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[s][2]; cout << " [2] "; pFun(); pFun = (Fun)pVtab[s][3]; cout << " [3] "; cout << pFun << endl; cout << "[" << s + 1 << "] Base2.ibase2 = " << (int)pVtab[s + 1] << endl; s = s + sizeof(Base2) / 4; cout << "[" << s << "] Base3::_vptr->" << endl; pFun = (Fun)pVtab[s][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[s][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[s][2]; cout << " [2] "; pFun(); pFun = (Fun)pVtab[s][3]; cout << " [3] "; cout << pFun << endl; s++; cout << "[" << s << "] Base3.ibase3 = " << (int)pVtab[s] << endl; s++; cout << "[" << s << "] Derive.iderive = " << (int)pVtab[s] << endl; return 0;}
Derive类的内存布局如下:
0 0
- C++对象内存布局-多重继承
- vs2008下C++对象内存布局(4):多重继承
- C++ 对象的内存布局(多重虚拟继承)
- 多重继承内存布局分析
- C++-对象继承中的内存布局
- 多重继承与虚继承 对象布局
- 浅析GCC下C++多重继承 & 虚拟继承的对象内存布局
- 浅析GCC下C++多重继承 & 虚拟继承的对象内存布局 - 问笑
- 类对象内存布局,虚函数,虚拟继承和多重继承的实现
- C++对象模型:多重继承和虚继承的内存布局
- 多重继承和虚继承的内存布局
- 多重继承和虚继承的内存布局
- 多重继承和虚继承的内存布局
- 多重继承和虚继承的内存布局
- 多重继承和虚继承的内存布局
- 多重继承和虚拟继承的内存布局
- 虚继承下的多重继承内存布局
- 多重继承和虚继承的内存布局
- 5.1面向对象<封装>(函数,类和对象)
- javaScript变量提升?
- ORA-00913: too many values 错误分析
- dlib::array2d<unsigned char> 与 cv::Mat 互转
- 时间序列分析(3)Python-最简单的回归
- C++对象内存布局-多重继承
- pycharm显示行号
- C++关于代码重用的那些事
- OpenWRT数据接收过程 二
- Linux Shell中的特殊符号和含义简明总结(包含了绝大部份)
- linux can 总线socket接口测试使用
- 队列
- vim命令
- Node