[cpp] C++对象内存布局分析
几年前整理的,最近有人问起,先放在这里,改天整理一下,前端时间忙,该开始整理一下笔记里的东西了,以后定时更新博客咯。
单继承模式下,虚继承
1: #ifndef OM_SINGLE_VIRTUAL_INHERITANCE_H_
2: #define OM_SINGLE_VIRTUAL_INHERITANCE_H_
3: // 单继承模式下,虚拟继承
4: // 若子类没有新定义virtual函数 此时子类的布局是 :
5: // 低地址 -> 高地址
6: // vbptr,子类的元素, 虚基类的元素.
7: // 在虚基类派生出来的类中,虚基类的位置一般情况下在存储区的尾部,需要一个中介才能访问虚基类的对象
8: // 所以虽然没有virtual函数,子类也需要有一个vbptr
9:
10: #include "om-port.h"
11: //////////////////////////////////////////////////////////////////////////
12: // 测试单一继承体系下的内存布局情况(虚拟继承)
13: namespace om_ns_svi {
14:
15: class CParent {
16: public:
17: CParent ():iparent_ (10) {}
18: int iparent_;
19: };
20:
21: class CChild_a : virtual public CParent {
22: public:
23: CChild_a():ichild_(100) {}
24: int ichild_;
25: };
26:
27: class CChild_b : virtual public CParent {
28: public:
29: CChild_b():ichild_(100) {}
30: virtual void f(){ cout<<"CChild_b::f()"<<endl;}
31: int ichild_;
32: };
33:
34: class CParent_vf {
35: public:
36: CParent_vf ():iparent_ (10) {}
37: virtual void f() { cout << "CParent_vf::f()" << endl;}
38: virtual void g() { cout << "CParent_vf::g()" << endl;}
39: int iparent_;
40: };
41:
42: class CChild_c : virtual public CParent_vf {
43: public:
44: CChild_c():ichild_(100) {}
45: virtual void f(){ cout << "CChild_c::f()" << endl;}
46: virtual void h(){ cout << "CChild_c::h()" << endl;}
47: int ichild_;
48: };
49:
50:
51: inline void TestSingleVirtualInheritance() {
52: #pragma warning(push)
53: #pragma warning(disable:4312 4311)
54:
55: int i = 0;
56: Ptr_Void_Fun pFun = NULL;
57: int** pVTable = NULL;
58: cout << " Test Single Virtual Inheritance "<<endl;
59: cout << "***************************************************************************" <<endl;
60: cout << endl << "--------------- Test CChild_a" << endl;
61: CChild_a cda;
62: pVTable = (int**)&cda;
63: cout << "size: " << sizeof(cda) << endl; // 有无虚函数都会有一个基类虚表指针
64: cout << (int*)&pVTable[0] << "\t" << "[0] CChild_a::vbptr" << endl;
65: cout << "\t\t\t" << "[0] CChild_a::vbptr for CChild_a (" << &pVTable[0][0] << ") = " <<pVTable[0][0]<< endl;
66: cout << "\t\t\t" << "[1] CChild_a::vbptr for CParent (" << &pVTable[0][1] << ") = " <<pVTable[0][1]<< endl;
67:
68: cout << (int*)&pVTable[1] << "\t" << "[1] CChild_a.ichild_ = " << (int)pVTable[1] << endl;
69: cout << (int*)&pVTable[2] << "\t" << "[2] CParent.iparent_ = " << (int)pVTable[2] << endl;
70:
71: cout << endl << "--------------- Test CChild_b" << endl;
72: CChild_b cdb;
73: pVTable = (int**)&cdb;
74: cout << "size: " << sizeof(cdb) << endl;
75: // 在GCC下,这种情况下的虚表最后一个入口不是一个函数
76: cout << (int*)&pVTable[0] << "\t" << "[0] CChild_b::vfptr->" << endl;
77: #if defined(OM_COMPILER_MSVC_)
78: for (i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
79: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
80: pFun = (Ptr_Void_Fun)pVTable[0][i];
81: pFun();
82: }
83: #else
84: for (i = 0; (Ptr_Void_Fun)pVTable[0][i+1] != NULL; i++) {
85: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
86: pFun = (Ptr_Void_Fun)pVTable[0][i];
87: pFun();
88: }
89: cout << "\t\t\t["<<i<<"] " << "\t" << &pVTable[0][i] << "\t" <<(int)pVTable[0][i] << endl;;
90: #endif
91:
92: #if defined(OM_COMPILER_MSVC_)
93: cout << (int*)&pVTable[1] << "\t" << "[1] CChild_b::vbptr" << endl;
94: cout << "\t\t\t" << "[0] CChild_b::vbptr for CChild_b (" << &pVTable[1][0] << ") = " <<pVTable[1][0]<< endl;
95: cout << "\t\t\t" << "[1] CChild_b::vbptr for CParent (" << &pVTable[1][1] << ") = " <<pVTable[1][1]<< endl;
96:
97: cout << (int*)&pVTable[2] << "\t" << "[2] CChild_b.ichild_ = " << (int)pVTable[2] << endl;
98: cout << (int*)&pVTable[3] << "\t" << "[3] CParent.iparent_ = " << (int)pVTable[3] << endl;
99: #else
100: cout << (int*)&pVTable[1] << "\t" << "[1] CChild_b.ichild_ = " << (int)pVTable[1] << endl;
101: cout << (int*)&pVTable[2] << "\t" << "[2] CParent.iparent_ = " << (int)pVTable[2] << endl;
102: #endif
103:
104: cout << endl << "--------------- Test CParent_vf" << endl;
105: CParent_vf cpvf;
106: pVTable = (int**)&cpvf;
107: cout << "size: " << sizeof(cpvf) << endl;
108: cout << (int*)&pVTable[0] << "\t" <<"[0] CParent::_vptr->" << endl;
109:
110: #if defined(OM_COMPILER_MSVC_)
111: for (i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
112: pFun = (Ptr_Void_Fun)pVTable[0][i];
113: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
114: pFun();
115: }
116: #else
117: for (i = 0; (Ptr_Void_Fun)pVTable[0][i+1] != NULL; i++) {
118: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
119: pFun = (Ptr_Void_Fun)pVTable[0][i];
120: pFun();
121: }
122: cout << "\t\t\t["<<i<<"] " << "\t" << &pVTable[0][i] << "\t" <<(int)pVTable[0][i] << endl;;
123: #endif
124:
125: cout << (int*)&pVTable[1] << "\t" << "[1] CParent.iparent_ = " << (int)pVTable[1] << endl;
126:
127: cout << endl << "--------------- Test CChild_c" << endl;
128: CChild_c cdc;
129: pVTable = (int**)&cdc;
130: cout << "size: " << sizeof(cdc) << endl; // 有无虚函数都会有一个基类虚表指针
131: cout << (int*)&pVTable[0] << "\t" << "[0] CChild_c::vfptr" << endl;
132:
133: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
134: pFun = (Ptr_Void_Fun)pVTable[0][i];
135: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
136: pFun();
137: }
138:
139:
140:
141: #if defined(OM_COMPILER_MSVC_)
142: cout << (int*)&pVTable[1] << "\t" << "[1] CChild_c::vbptr" << endl;
143: cout << "\t\t\t" << "[0] CChild_c::vbptr for CChild_b (" << &pVTable[1][0] << ") = " <<pVTable[1][0]<< endl;
144: cout << "\t\t\t" << "[1] CChild_c::vbptr for CParent_vf (" << &pVTable[1][1] << ") = " <<pVTable[1][1]<< endl;
145:
146: cout << (int*)&pVTable[2] << "\t" << "[2] CChild_c.ichild_ = " << (int)pVTable[2] << endl;
147: cout << (int*)&pVTable[3] << "\t" << "[3] CParent_vf::vfptr->" << endl;
148: for (int i = 0; (Ptr_Void_Fun)pVTable[3][i] != NULL; i++) {
149: pFun = (Ptr_Void_Fun)pVTable[3][i];
150: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[3][i]<<"\t";
151: pFun();
152: }
153: cout << (int*)&pVTable[4] << "\t" << "[4] CParent.iparent_ = " << (int)pVTable[4] << endl;
154: #else
155: cout << (int*)&pVTable[1] << "\t" << "[1] CChild_c.ichild_ = " << (int)pVTable[1] << endl;
156: cout << (int*)&pVTable[2] << "\t" << "[2] CParent_vf::vfptr->" << endl;
157: for (int i = 0; (Ptr_Void_Fun)pVTable[2][i] != NULL; i++) {
158: pFun = (Ptr_Void_Fun)pVTable[2][i];
159: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[2][i]<<"\t";
160: pFun();
161: }
162: cout << (int*)&pVTable[3] << "\t" << "[3] CParent.iparent_ = " << (int)pVTable[3] << endl;
163: #endif
164: #pragma warning(pop)
165: cout << endl;
166: }
167: }//om_ns_svi
168:
169: #endif
单一继承体系下的内存布局情况(非虚继承)
1: #ifndef OM_SINGLE_INHERITANCE_H_
2: #define OM_SINGLE_INHERITANCE_H_
3:
4: //////////////////////////////////////////////////////////////////////////
5: // 测试单一继承体系下的内存布局情况(非虚拟继承)
6: // class:
7: // CParent
8: // CChild : public CParent
9: // CGrandChild : public CChild
10: // CParent_no_virtual
11: // CParent_no_virtual : CChild_no_virtual
12:
13: // 单继承模式下,如果是普通继承,而且父类没有virtual函数
14: //
15: // 1:若子类没有新定义virtual函数 此时子类的布局是 :
16: // 低地址->高地址
17: // 父类的元素(没有vfptr),子类的元素(没有vfptr).
18: // 2:若子类有新定义virtual函数 此时子类的布局是 :
19: // 低地址 -> 高地址
20: // vfptr,指向vtable, 父类的元素(没有vfptr), 子类的元素
21:
22: // 单继承模式下,如果是普通继承,而且父类有virtual函数
23: // 不管子类没有新定义virtual函数 此时子类的布局是 :
24: // 低地址 -> 高地址
25: // vfptr +父类的元素, 子类的元素.
26: // 子类与父类公用虚表,子类更新父类的虚表.
27:
28:
29: #include "om-port.h"
30:
31: namespace om_ns_si {
32: class CParent {
33: public:
34: CParent ():iparent_ (10) {}
35: virtual ~CParent(){}
36: virtual void f() { cout << "CParent::f()" << endl; }
37: virtual void g() { cout << "CParent::g()" << endl; }
38: virtual void h() { cout << "CParent::h()" << endl; }
39: virtual void c() { cout << "CParent::c()" << endl;}
40: int iparent_;
41: };
42: class CChild : public CParent {
43: public:
44: CChild():ichild_(100) {}
45: virtual void f() { cout << "CChild::f()" << endl; }
46: virtual void g1() { cout << "CChild::g1()" << endl; }
47: virtual void h1() { cout << "CChild::h1()" << endl; }
48: int ichild_;
49: };
50: class CGrandChild : public CChild{
51: public:
52: CGrandChild():igrandchild_(1000) {}
53: virtual void f() { cout << "CGrandChild::f()" << endl; }
54: virtual void g1() { cout << "CGrandChild::g1()" << endl; }
55: virtual void h2() { cout << "CGrandChild::h2()" << endl; }
56: virtual void c() { cout << "CGrandChild::c()" << endl;}
57: int igrandchild_;
58: };
59:
60:
61: class CParent_no_virtual {
62: public:
63: CParent_no_virtual ():iparent_no_virtual_ (20) {}
64: int iparent_no_virtual_;
65: };
66: class CChild_no_virtual :public CParent_no_virtual {
67: public:
68: CChild_no_virtual ():ichild_no_virtual_ (200) {}
69: int ichild_no_virtual_;
70: };
71:
72: inline void TestSingleInheritance() {
73: #pragma warning(push)
74: #pragma warning(disable:4312 4311)
75:
76: cout << " Test Single Inheritance "<<endl;
77: cout << "***************************************************************************" <<endl;
78: int i = 0;
79: Ptr_Void_Fun pFun = NULL;
80: int** pVTable = NULL;
81:
82: cout << endl <<"---------------Test CParent_no_virtual"<< endl;
83: CParent_no_virtual cpnv;
84: pVTable = (int**)&cpnv;
85: cout << "size: " << sizeof(cpnv) << endl;
86: cout << (int*)&pVTable[0] << "\t" << "[1] CParent_no_virtual.iparent_no_virtual_ = " << (int)pVTable[0] << endl;
87:
88: cout << endl <<"--------------- Test CChild_no_virtual " << endl;
89: CChild_no_virtual ccnv;
90: pVTable = (int**)&ccnv;
91: cout << "size: " << sizeof(ccnv) << endl;
92: cout << (int*)&pVTable[0] << "\t" << "[0] CParent_no_virtual.iparent_no_virtual_ = " << (int)pVTable[0] << endl;
93: cout << (int*)&pVTable[1] << "\t" << "[1] CChild_no_virtual.ichild_no_virtual_ = " << (int)pVTable[1] << endl;
94:
95:
96: cout << endl <<"--------------- Test CParent" << endl;
97: CParent cp;
98: pVTable = (int**)&cp;
99: cout << "size: " << sizeof(cp) << endl;
100:
101: cout << (int*)&pVTable[0] << "\t" <<"[0] CParent::vfptr->" << endl;
102:
103: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
104: pFun = (Ptr_Void_Fun)pVTable[0][i];
105: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
106: if(i != DESTRUCTURE_IGNORE_1 && i!=DESTRUCTURE_IGNORE_2)
107: pFun();
108: else
109: cout<<"Perhaps Destruct"<<endl;
110: }
111: cout << (int*)&pVTable[1] << "\t" << "[1] CParent.iparent_ = " << (int)pVTable[1] << endl;
112:
113: cout << endl <<"--------------- Test CChild" << endl;
114: CChild cd;
115: pVTable = (int**)&cd;
116: cout << "size: " << sizeof(cd) << endl;
117:
118: cout << (int*)&pVTable[0] << "\t" <<"[0] CChild::CParent::vfptr->" << endl;
119:
120: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
121: pFun = (Ptr_Void_Fun)pVTable[0][i];
122: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
123: if(i != DESTRUCTURE_IGNORE_1 && i!=DESTRUCTURE_IGNORE_2)
124: pFun();
125: else
126: cout<<"Perhaps Destruct"<<endl;
127: }
128: cout << (int*)&pVTable[1] << "\t" << "[1] CParent.iparent_ = " << (int)pVTable[1] << endl;
129: cout << (int*)&pVTable[2] << "\t" << "[2] CChild.ichild_ = " << (int)pVTable[2] << endl;
130:
131: cout << endl <<"--------------- Test CGrandChild" << endl;
132: CGrandChild gc;
133: pVTable = (int**)&gc;
134:
135: cout << "size: " << sizeof(gc) << endl;
136: cout << (int*)&pVTable[0] << "\t" << "[0] CGrandChild::CChild::CParent::vfptr->" << endl;
137: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
138: pFun = (Ptr_Void_Fun)pVTable[0][i];
139: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
140: if(i != DESTRUCTURE_IGNORE_1 && i!=DESTRUCTURE_IGNORE_2)
141: pFun();
142: else
143: cout<<"Perhaps Destruct"<<endl;
144: }
145: cout << (int*)&pVTable[1] << "\t" << "[1] CParent.iparent_ = " << (int)pVTable[1] << endl;
146: cout << (int*)&pVTable[2] << "\t" << "[2] CChild.ichild_ = " << (int)pVTable[2] << endl;
147: cout << (int*)&pVTable[3] << "\t" << "[3] CGrandChild.igrandchild_ = " << (int)pVTable[3] << endl;
148: #pragma warning(pop)
149: cout<<endl;
150: }
151: } // om_ns_si
152: #endif
简单多继承
1: #ifndef OM_MULTIPLE_INHERITANCE_H_
2: #define OM_MULTIPLE_INHERITANCE_H_
3:
4: #include "om-port.h"
5:
6: namespace om_ns_mi{
7: class CParent_a {
8: public:
9: CParent_a ():iparent_ (10) {}
10: virtual void f() { cout << "CParent_a::f()" << endl; }
11: virtual void g() { cout << "CParent_a::g()" << endl; }
12: virtual void h() { cout << "CParent_a::h()" << endl; }
13: int iparent_;
14: };
15:
16: class CParent_b {
17: public:
18: CParent_b ():iparent_ (20) {}
19: virtual void f() { cout << "CParent_a::f()" << endl; }
20: virtual void g() { cout << "CParent_a::g()" << endl; }
21: virtual void h() { cout << "CParent_a::h()" << endl; }
22: int iparent_;
23: };
24:
25: class CChild_m : public CParent_a,public CParent_b {
26: public:
27: CChild_m() : ichild_(1020){}
28: virtual void f() { cout << "CChild::f()" << endl; }
29: virtual void g() { cout << "CChild::g()" << endl; }
30: int ichild_;
31: };
32:
33: void TestMutipleInheritance(){
34:
35: cout << " Test Multiple Inheritance "<<endl;
36: cout << "***************************************************************************" <<endl;
37:
38: int i = 0;
39: Ptr_Void_Fun pFun = NULL;
40: int** pVTable = NULL;
41:
42: CChild_m cc;
43: pVTable = (int**)&cc;
44: cout << "size: " << sizeof(cc) << endl;
45: cout << (int*)&pVTable[0] << "\t" << "[0] CChild_m::CParent_a::vfptr->" << endl;
46:
47: #if defined(OM_COMPILER_MSVC_)
48: for (i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
49: pFun = (Ptr_Void_Fun)pVTable[0][i];
50: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
51: pFun();
52: }
53: #else
54: for (i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL && pVTable[2][i] > -100 && pVTable[2][i] < 100; i++) {
55: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
56: pFun = (Ptr_Void_Fun)pVTable[0][i];
57: pFun();
58: }
59: cout << "\t\t\t["<<i<<"] " << "\t" << &pVTable[0][i] << "\t" <<(int)pVTable[0][i] << endl;
60: #endif
61:
62: cout << (int*)&pVTable[1] << "\t" << "[1] CParent_a.iparent_ = " << (int)pVTable[1] << endl;
63:
64: cout << (int*)&pVTable[2] << "\t" << "[0] CChild_m::CParent_b::vfptr->" << endl;
65: for (int i = 0; (Ptr_Void_Fun)pVTable[2][i] != NULL; i++) {
66: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[2][i]<<"\t";
67: pFun = (Ptr_Void_Fun)pVTable[2][i];
68: pFun();
69: }
70: cout << (int*)&pVTable[3] << "\t" << "[3] CParent_a.iparent_ = " << (int)pVTable[3] << endl;
71: cout << (int*)&pVTable[4] << "\t" << "[4] CChild_m.ichild_ = " << (int)pVTable[4] << endl;
72: }
73: }
74:
75: #endif
多重继承(2层),有虚继承的情况存在
1: #ifndef OM_MULTIPLE_VIRTUAL_INHERITANCE_H_
2: #define OM_MULTIPLE_VIRTUAL_INHERITANCE_H_
3: #include "om-port.h"
4:
5: // 多重继承(2层),有虚继承的情况存在
6: // 首先排列非虚继承的基类实例;
7: // 有虚基类时,为每个基类增加一个隐藏的vbptr,除非已经从非虚继承的类那里继承了一个vbptr;
8: // 排列派生类的新数据成员;
9: // 在实例最后,排列每个虚基类的一个实例
10:
11: // 在单继承和多重继承的情况下,内嵌的基类实例地址比起派生类实例地址,
12: // 或者地址相同(单继承,以及多重继承的最靠左基类),或者是地址相差一个固定偏移量(多重继承的非最靠左基类)
13:
14: // 一般情况下派生类地址和其虚基类地址之间的偏移量是不固定的,因为如果这个派生类又被进一步继承的话,
15: // 最终派生类会把共享的虚基类实例数据放到一个与上一层派生类不同的偏移量处
16: // 例子中的CParent对于CChild_av,CChild_bv的偏移地址是不确定的,如果继续派生,那么偏移地址还会变化.
17:
18: // 如果使用指针访问虚基类成员变量时,由于指针可以是指向派生类实例的基类指针,
19: // 编译器不能根据声明的指针类型计算偏移,而必须找到另一种间接的方法,从派生类指针计算虚基类的位置。
20: // 这时可以使用vbptr指向的虚基类表中存储的数值进行计算。
21:
22: namespace om_ns_mvi{
23: class CParent_a {
24: public:
25: CParent_a ():iparent_ (10) {}
26: virtual void f() { cout << "CParent_a::f()" << endl; }
27: virtual void g() { cout << "CParent_a::g()" << endl; }
28: virtual void h() { cout << "CParent_a::h()" << endl; }
29: int iparent_;
30: };
31:
32: class CParent_b {
33: public:
34: CParent_b ():iparent_ (20) {}
35: virtual void f() { cout << "CParent_a::f()" << endl; }
36: virtual void g() { cout << "CParent_a::g()" << endl; }
37: virtual void h() { cout << "CParent_a::h()" << endl; }
38: int iparent_;
39: };
40:
41: class CChild_mv : virtual public CParent_a,public CParent_b {
42: public:
43: CChild_mv() : ichild_(1020){}
44: virtual void f() { cout << "CChild_mv::f()" << endl; }
45: virtual void g() { cout << "CChild_mv::g()" << endl; }
46: virtual void cc() { cout << "CChild_mv::cc()" << endl; }
47: int ichild_;
48: };
49:
50: class CChild_mvv : virtual public CParent_a,virtual public CParent_b {
51: public:
52: CChild_mvv() : ichild_(2010){}
53: virtual void f() { cout << "CChild_mvv::f()" << endl; }
54: virtual void g() { cout << "CChild_mvv::g()" << endl; }
55: virtual void cc() { cout << "CChild_mvv::cc()" << endl; }
56: int ichild_;
57: };
58:
59: void TestMutipleVirtualInheritance(){
60:
61: cout << " Test Multiple Virtual Inheritance "<<endl;
62: cout << "***************************************************************************" <<endl;
63: cout << endl << "--------------- Test CChild_mv" << endl;
64: int i = 0;
65: Ptr_Void_Fun pFun = NULL;
66: int** pVTable = NULL;
67:
68: CChild_mv ccmv;
69: pVTable = (int**)&ccmv;
70: cout << "size: " << sizeof(ccmv) << endl;
71: cout << (int*)&pVTable[0] << "\t" << "[0] CChild_mv::CParent_b::vfptr->" << endl;
72: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
73: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
74: pFun = (Ptr_Void_Fun)pVTable[0][i];
75: pFun();
76: }
77:
78: cout << (int*)&pVTable[1] << "\t" << "[1] CParent_b.iparent_ = " << (int)pVTable[1] << endl;
79:
80: #if defined(OM_COMPILER_MSVC_)
81: cout << (int*)&pVTable[2] << "\t" << "[2] CChild_mv::vbptr->" << endl;
82: cout << "\t\t\t" << "[0] CChild_mv::vbptr for CChild_mv (" << &pVTable[2][0] << ") = " <<pVTable[2][0]<< endl;
83: cout << "\t\t\t" << "[1] CChild_mv::vbptr for CParent_a (" << &pVTable[2][1] << ") = " <<pVTable[2][1]<< endl;
84:
85: cout << (int*)&pVTable[3] << "\t" << "[3] CChild_mv.ichild_ = " << (int)pVTable[3] << endl;
86:
87: cout << (int*)&pVTable[4] << "\t" << "[4] CParent_a::vfptr->" << endl;
88: for (int i = 0; (Ptr_Void_Fun)pVTable[4][i] != NULL; i++) {
89: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[4][i]<<"\t";
90: pFun = (Ptr_Void_Fun)pVTable[4][i];
91: pFun();
92: }
93: cout << (int*)&pVTable[5] << "\t" << "[5] CParent_a.iparent_ = " << (int)pVTable[5] << endl;
94: #else
95: cout << (int*)&pVTable[2] << "\t" << "[2] CChild_mv.ichild_ = " << (int)pVTable[2] << endl;
96:
97: cout << (int*)&pVTable[3] << "\t" << "[3] CParent_a::vfptr->" << endl;
98: for (int i = 0; (Ptr_Void_Fun)pVTable[3][i] != NULL; i++) {
99: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[3][i]<<"\t";
100: pFun = (Ptr_Void_Fun)pVTable[3][i];
101: pFun();
102: }
103: cout << (int*)&pVTable[4] << "\t" << "[4] CParent_a.iparent_ = " << (int)pVTable[4] << endl;
104: #endif
105:
106: cout << endl << "--------------- Test CChild_mvv" << endl;
107: CChild_mvv ccmvv;
108: pVTable = (int**)&ccmvv;
109: cout << "size: " << sizeof(ccmvv) << endl;
110: cout << (int*)&pVTable[0] << "\t" << "[0] CChild_mvv::vfptr->" << endl;
111: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
112: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
113: pFun = (Ptr_Void_Fun)pVTable[0][i];
114: pFun();
115: }
116:
117: #if defined(OM_COMPILER_MSVC_)
118: cout << (int*)&pVTable[1] << "\t" << "[1] CChild_mvv::vbptr->" << endl;
119: cout << "\t\t\t" << "[0] CChild_mv::vbptr for CChild_mv (" << &pVTable[1][0] << ") = " <<pVTable[1][0]<< endl;
120: cout << "\t\t\t" << "[1] CChild_mv::vbptr for CParent_a (" << &pVTable[1][1] << ") = " <<pVTable[1][1]<< endl;
121: cout << "\t\t\t" << "[1] CChild_mv::vbptr for CParent_b (" << &pVTable[1][1] << ") = " <<pVTable[1][2]<< endl;
122: cout << (int*)&pVTable[2] << "\t" << "[2] CChild_mvv.ichild_ = " << (int)pVTable[2] << endl;
123:
124:
125: cout << (int*)&pVTable[3] << "\t" << "[3] CParent_a::vfptr->" << endl;
126: for (int i = 0; (Ptr_Void_Fun)pVTable[3][i] != NULL; i++) {
127: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[3][i]<<"\t";
128: pFun = (Ptr_Void_Fun)pVTable[3][i];
129: pFun();
130: }
131: cout << (int*)&pVTable[4] << "\t" << "[4] CParent_a.iparent_ = " << (int)pVTable[4] << endl;
132:
133: cout << (int*)&pVTable[5] << "\t" << "[5] CParent_b::vfptr->" << endl;
134: for (int i = 0; (Ptr_Void_Fun)pVTable[5][i] != NULL; i++) {
135: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[5][i]<<"\t";
136: pFun = (Ptr_Void_Fun)pVTable[5][i];
137: pFun();
138: }
139: cout << (int*)&pVTable[6] << "\t" << "[6] CParent_b.iparent_ = " << (int)pVTable[6] << endl;
140: #else
141: cout << (int*)&pVTable[1] << "\t" << "[2] CChild_mvv.ichild_ = " << (int)pVTable[1] << endl;
142:
143:
144: cout << (int*)&pVTable[2] << "\t" << "[2] CParent_a::vfptr->" << endl;
145: for (i = 0; (Ptr_Void_Fun)pVTable[2][i] != NULL; i++) {
146: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[2][i]<<"\t";
147: pFun = (Ptr_Void_Fun)pVTable[2][i];
148: pFun();
149: }
150:
151: cout << (int*)&pVTable[3] << "\t" << "[3] CParent_a.iparent_ = " << (int)pVTable[3] << endl;
152:
153: cout << (int*)&pVTable[4] << "\t" << "[4] CParent_b::vfptr->" << endl;
154: for (int i = 0; (Ptr_Void_Fun)pVTable[4][i] != NULL; i++) {
155: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[4][i]<<"\t";
156: pFun = (Ptr_Void_Fun)pVTable[4][i];
157: pFun();
158: }
159: cout << (int*)&pVTable[5] << "\t" << "[5] CParent_b.iparent_ = " << (int)pVTable[5] << endl;
160: #endif
161: }
162: }
163:
164: #endif
三层继承体系简要分析代码(包括不合理继承和钻石继承)
1: #ifndef OM_TRIPLE_INHERITANCE_H_
2: #define OM_TRIPLE_INHERITANCE_H_
3:
4: // 三层继承体系分析
5:
6: #include "om-port.h"
7:
8: namespace om_ns_ti{
9: class CParent {
10: public:
11: CParent ():iparent_ (10) {}
12: virtual void f() { cout << "CParent::f()" << endl; }
13: virtual void g() { cout << "CParent::g()" << endl; }
14: virtual void h() { cout << "CParent::h()" << endl; }
15: virtual void c() { cout << "CParent::c()" << endl;}
16: int iparent_;
17: };
18: class CChild_a : public CParent {
19: public:
20: CChild_a():ichild_(100) {}
21: virtual void f() { cout << "CChild_a::f()" << endl; }
22: virtual void g1() { cout << "CChild_a::g1()" << endl; }
23: virtual void h1() { cout << "CChild_a::h1()" << endl; }
24: virtual void g() { cout << "CChild_a::g()" << endl; }
25: int ichild_;
26: };
27: class CChild_b : public CParent {
28: public:
29: CChild_b():ichild_(200) {}
30: virtual void f() { cout << "CChild_b::f()" << endl; }
31: virtual void g1() { cout << "CChild_b::g1()" << endl; }
32: virtual void h1() { cout << "CChild_b::h1()" << endl; }
33: int ichild_;
34: };
35: class CGrandChild : public CChild_a,public CChild_b{
36: public:
37: CGrandChild():igrandchild_(1000) {}
38: virtual void f() { cout << "CGrandChild::f()" << endl; }
39: virtual void g1() { cout << "CGrandChild::g1()" << endl; }
40: virtual void h2() { cout << "CGrandChild::h2()" << endl; }
41: virtual void c() { cout << "CGrandChild::c()" << endl;}
42: virtual void g() { cout << "CGrandChild::g()" << endl; }
43: int igrandchild_;
44: };
45:
46: class CChild_av : virtual public CParent {
47: public:
48: CChild_av():ichild_(100) {}
49: virtual void f() { cout << "CChild_av::f()" << endl; }
50: virtual void g1() { cout << "CChild_av::g1()" << endl; }
51: virtual void h1() { cout << "CChild_av::h1()" << endl; }
52: virtual void g() { cout << "CChild_av::g()" << endl; }
53: int ichild_;
54: };
55: class CChild_bv : virtual public CParent {
56: public:
57: CChild_bv():ichild_(200) {}
58: virtual void f() { cout << "CChild_bv::f()" << endl; }
59: virtual void g1() { cout << "CChild_bv::g1()" << endl; }
60: virtual void h1() { cout << "CChild_bv::h1()" << endl; }
61: int ichild_;
62: };
63: class CGrandChild_v : public CChild_av,public CChild_bv{
64: public:
65: CGrandChild_v():igrandchild_(1000) {}
66: virtual void f() { cout << "CGrandChild_v::f()" << endl; }
67: virtual void g1() { cout << "CGrandChild_v::g1()" << endl; }
68: virtual void h2() { cout << "CGrandChild_v::h2()" << endl; }
69: virtual void c() { cout << "CGrandChild_v::c()" << endl;}
70: //virtual void g() { cout << "CGrandChild_v::g()" << endl; }
71: int igrandchild_;
72: };
73:
74: void TestTripleInheritance() {
75: cout << " Test Triple Inheritance "<<endl;
76: cout << "***************************************************************************" <<endl;
77:
78: int i = 0;
79: Ptr_Void_Fun pFun = NULL;
80: int** pVTable = NULL;
81:
82: cout << endl << "--------------- Test CGrandChild" << endl;
83: CGrandChild cgc;
84: pVTable = (int**)&cgc;
85: cout << "size: " << sizeof(cgc) << endl;
86: cout << (int*)&pVTable[0] << "\t" << "[0] CGrandChild::CChild_a::CParent::vfptr->" << endl;
87:
88: #if defined(OM_COMPILER_MSVC_)
89: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
90: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
91: pFun = (Ptr_Void_Fun)pVTable[0][i];
92: pFun();
93: }
94: #else
95: for (i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL && pVTable[0][i] > -100 && pVTable[0][i] < 100; i++) {
96: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
97: pFun = (Ptr_Void_Fun)pVTable[0][i];
98: pFun();
99: }
100: cout << "\t\t\t["<<i<<"] " << "\t" << &pVTable[0][i] << "\t" <<(int)pVTable[0][i] << endl;
101: #endif
102: cout << (int*)&pVTable[1] << "\t" << "[1] CParent.iparent_ = " << (int)pVTable[1] << endl;
103: cout << (int*)&pVTable[2] << "\t" << "[2] CGrandChild::CChild_a.ichild_ = " << (int)pVTable[2] << endl;
104: cout << (int*)&pVTable[3] << "\t" << "[3] CGrandChild::CChild_b::CParent::vfptr->" << endl;
105: for (int i = 0; (Ptr_Void_Fun)pVTable[3][i] != NULL; i++) {
106: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[3][i]<<"\t";
107: pFun = (Ptr_Void_Fun)pVTable[3][i];
108: pFun();
109: }
110:
111: cout << (int*)&pVTable[4] << "\t" << "[4] CParent.iparent_ = " << (int)pVTable[4] << endl;
112: cout << (int*)&pVTable[5] << "\t" << "[5] CGrandChild::CChild_b.ichild_ = " << (int)pVTable[5] << endl;
113: cout << (int*)&pVTable[6] << "\t" << "[6] CGrandChild::ichild_ = " << (int)pVTable[6] << endl;
114:
115: cout << endl << "--------------- Test CGrandChild_v" << endl;
116: CGrandChild_v cgcv;
117: pVTable = (int**)&cgcv;
118: cout << "size: " << sizeof(cgcv) << endl;
119: cout << (int*)&pVTable[0] << "\t" << "[0] CGrandChild_v::CChild_av::vfptr->" << endl;
120: #if defined(OM_COMPILER_MSVC_)
121: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL; i++) {
122: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
123: pFun = (Ptr_Void_Fun)pVTable[0][i];
124: pFun();
125: }
126: #else
127: for (int i = 0; (Ptr_Void_Fun)pVTable[0][i] != NULL && pVTable[0][i] > -100 && pVTable[0][i] < 100; i++) {
128: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[0][i]<<"\t";
129: pFun = (Ptr_Void_Fun)pVTable[0][i];
130: pFun();
131: }
132: cout << "\t\t\t["<<i<<"] " << "\t" << &pVTable[0][i] << "\t" <<(int)pVTable[0][i] << endl;
133: #endif
134:
135: #if defined(OM_COMPILER_MSVC_)
136: cout << (int*)&pVTable[1] << "\t" << "[1] CGrandChild_v::CChild_av::vbptr" << endl;
137: cout << "\t\t\t" << "[0] CChild_b::vbptr for CChild_av (" << &pVTable[1][0] << ") = " <<pVTable[1][0]<< endl;
138: cout << "\t\t\t" << "[1] CChild_b::vbptr for CParent (" << &pVTable[1][1] << ") = " <<pVTable[1][1]<< endl;
139:
140: cout << (int*)&pVTable[2] << "\t" << "[2] CGrandChild::CChild_av.ichild_ = " << (int)pVTable[2] << endl;
141:
142: cout << (int*)&pVTable[3] << "\t" << "[3] CGrandChild_v::CChild_bv::vfptr->" << endl;
143: for (int i = 0; (Ptr_Void_Fun)pVTable[3][i] != NULL; i++) {
144: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[3][i]<<"\t";
145: pFun = (Ptr_Void_Fun)pVTable[3][i];
146: pFun();
147: }
148: cout << (int*)&pVTable[4] << "\t" << "[1] CGrandChild_v::CChild_bv::vbptr" << endl;
149: cout << "\t\t\t" << "[0] CChild_b::vbptr for CChild_bv (" << &pVTable[4][0] << ") = " <<pVTable[4][0]<< endl;
150: cout << "\t\t\t" << "[1] CChild_b::vbptr for CParent (" << &pVTable[4][1] << ") = " <<pVTable[4][1]<< endl;
151:
152: cout << (int*)&pVTable[5] << "\t" << "[5] CGrandChild::CChild_bv.ichild_ = " << (int)pVTable[5] << endl;
153: cout << (int*)&pVTable[6] << "\t" << "[6] CGrandChild::ichild_ = " << (int)pVTable[6] << endl;
154:
155: cout << (int*)&pVTable[7] << "\t" << "[7] CParent::vfptr->" << endl;
156: for (int i = 0; (Ptr_Void_Fun)pVTable[7][i] != NULL; i++) {
157: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[7][i]<<"\t";
158: pFun = (Ptr_Void_Fun)pVTable[7][i];
159: pFun();
160: }
161: cout << (int*)&pVTable[8] << "\t" << "[8] CParent::iparent_ = " << (int)pVTable[8] << endl;
162: #else
163: cout << (int*)&pVTable[1] << "\t" << "[1] CGrandChild::CChild_av.ichild_ = " << (int)pVTable[1] << endl;
164:
165: cout << (int*)&pVTable[2] << "\t" << "[2] CGrandChild_v::CChild_bv::vfptr->" << endl;
166: for (int i = 0; (Ptr_Void_Fun)pVTable[2][i] != NULL && pVTable[2][i] > -100 && pVTable[2][i] < 100; i++) {
167: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[2][i]<<"\t";
168: pFun = (Ptr_Void_Fun)pVTable[2][i];
169: pFun();
170: }
171: cout << "\t\t\t["<<i<<"] " << "\t" << &pVTable[0][i] << "\t" <<(int)pVTable[0][i] << endl;
172: cout << (int*)&pVTable[3] << "\t" << "[3] CGrandChild::CChild_bv.ichild_ = " << (int)pVTable[3] << endl;
173: cout << (int*)&pVTable[4] << "\t" << "[4] CGrandChild::ichild_ = " << (int)pVTable[4] << endl;
174: cout << (int*)&pVTable[5] << "\t" << "[5] CParent::vfptr->" << endl;
175: for (int i = 0; (Ptr_Void_Fun)pVTable[5][i] != NULL; i++) {
176: cout << "\t\t\t["<<i<<"] " << "\t" << (int*)pVTable[5][i]<<"\t";
177: pFun = (Ptr_Void_Fun)pVTable[5][i];
178: pFun();
179: }
180: cout << (int*)&pVTable[6] << "\t" << "[8] CParent::iparent_ = " << (int)pVTable[8] << endl;
181: #endif
182: }
183: }
184:
185: #endif