一、前言
在看了皓哥的C++对象的布局之后:http://blog.csdn.net/haoel/article/details/3081328。感觉自己还是总是不能记得很清楚,故在此总结一下C++对象的内存布局,一遍以后及时复习。
二、
- 单一非虚继承:有成员变量,有虚函数和虚函数的覆盖,不是虚拟继承
源码如下:
#include <iostream> using namespace std; class Parent { public: int iparent; Parent() : iparent(10) {} virtual void f() { cout << "Parent::f()" << endl; } virtual void g() { cout << "Parent::g()" << endl; } virtual void h() { cout << "Parent::g()" << endl; } }; class Child : public Parent { public: int ichild; Child() : ichild(100) {} virtual void f() { cout << "Child::f()" << endl; } virtual void g_child() { cout << "Child::g_child()" << endl; } virtual void h_child() { cout << "Child::h_child()" << endl; } }; class GrandChild : public Child { public: int igrandchild; GrandChild() : igrandchild(1000) {}; virtual void f() { cout << "GrandChild::f()" << endl; } virtual void g_child() { cout << "GrandChild::g_child()" << endl; } virtual void h_gradnchild() { cout << "GrandChild::h_grandchild()" << endl; } }; int main(int argc, char **argv) { GrandChild gc; typedef void(*Fun)(void); Fun pf; cout << "[0] GrandChild::vfptr->" << endl; cout << " [0]"; pf = (Fun)*(int *)*(int *)&gc; pf(); cout << " [1]"; pf = (Fun)*((int *)*(int *)&gc + 1); pf(); cout << " [2]"; pf = (Fun)*((int *)*(int *)&gc + 2); pf(); cout << " [3]"; pf = (Fun)*((int *)*(int *)&gc + 3); pf(); cout << " [4]"; pf = (Fun)*((int *)*(int *)&gc + 4); pf(); cout << " [5]"; pf = (Fun)*((int *)*(int *)&gc + 5); pf(); cout << "[1] Parent.iparent = " << (int)(*((int *)&gc + 1)) << endl; cout << "[2] Child.ichild = " << (int)(*((int *)&gc + 2)) << endl; cout << "[3] GrandChild.igrandchild = " << (int)(*((int *)&gc + 3)) << endl; return 0; }
代码运行结果如下:
[0] GrandChild::vfptr-> [0]GrandChild::f() [1]Parent::g() [2]Parent::g() [3]GrandChild::g_child() [4]Child::h_child() [5]GrandChild::h_grandchild() [1] Parent.iparent = 10 [2] Child.ichild = 100 [3] GrandChild.igrandchild = 1000
由此可见,在这种继承关系下,一个对象会有一个被称作虚函数表指针的vfptr。接着会存放Parent -> Child -> GrandChild。这里直接把皓哥的图片拿来用了:
可以看出:1.虚函数表指针在整个对象的最前面;
2.基类数据成员放在派生类的前面;
3.在虚函数表中派生类覆盖的函数得到了更新。
sizeof(gc) = 16 : sizeof( vfptr ) + 3 * sizeof( int )