C++对象模型之内存布局(3)

简单的虚继承

#include <iostream>
using namespace std;

class A
{
public:
	A(int a1 = 0, int a2 = 0) {};
	~A() {};
	virtual void A1() { cout << "A::A1() " << endl; };
	virtual void A2() { cout << "A::A2() " << endl; };

protected:
	int a1;
	int a2;
};

class C : virtual public A
{
public:
	C(int a1 = 0, int a2 = 0, int c1 = 0):A(a1,a2), c1(c1) {};
	~C() {};
	virtual void C1() { cout << "C::C1() " << endl; };
	virtual void C2() { cout << "C::C2() " << endl; };

protected:
	int c1;
};


typedef void(*pfun)(); //函数指针
int main()
{
	C *bp = new C;
	pfun fun = NULL;

	cout << "C的虚函数表" << endl;
	for (size_t i = 0; i < 2; i++)
	{
		fun = (pfun)*((long *)*(long*)bp + i);
		fun();
	}
	cout << "A的虚函数表" << endl;
	long* cp = (long*)bp + 3;
	for (size_t i = 0; i < 2; i++)
	{
		fun = (pfun)*((long *)*(long*)cp + i);
		fun();
	}
	cout << *((long *)*cp + 2) << endl;
	system("PAUSE");
}

运行结果:

C的虚函数表
C::C1()
C::C2()
A的虚函数表
A::A1()
A::A2()
0
请按任意键继续. . .

简单解释一下:当存在虚基类时,先是子类的成员,然后才是虚基类的成员。

 

class C size(24):
        +---
 0      | {vfptr}
 4      | {vbptr}
 8      | c1
        +---
        +--- (virtual base A)
12      | {vfptr}
16      | a1
20      | a2
        +---

C::$vftable@C@:
        | &C_meta
        |  0
 0      | &C::C1
 1      | &C::C2

C::$vbtable@:
 0      | -4
 1      | 8 (Cd(C+4)A)

C::$vftable@A@:
        | -12
 0      | &A::A1
 1      | &A::A2

 如果将C类中的C1改为A1,代码如下

#include <iostream>
using namespace std;

class A
{
public:
	A(int a1 = 0, int a2 = 0) {};
	~A() {};
	virtual void A1() { cout << "A::A1() " << endl; };
	virtual void A2() { cout << "A::A2() " << endl; };

protected:
	int a1;
	int a2;
};

class C : virtual public A
{
public:
	C(int a1 = 0, int a2 = 0, int c1 = 0):A(a1,a2), c1(c1) {};
	~C() {};
	virtual void A1() { cout << "C::C1() " << endl; };
	virtual void C2() { cout << "C::C2() " << endl; };

protected:
	int c1;
};


typedef void(*pfun)(); //函数指针
int main()
{
	C *bp = new C;
	pfun fun = NULL;

	cout << "C的虚函数表" << endl;
	for (size_t i = 0; i < 1; i++)
	{
		fun = (pfun)*((long *)*(long*)bp + i);
		fun();
	}
	cout << "A的虚函数表" << endl;
	long* cp = (long*)bp + 4;
	for (size_t i = 0; i < 2; i++)
	{
		fun = (pfun)*((long *)*(long*)cp + i);
		fun();
	}
	cout << *((long *)*cp + 2) << endl;
	system("PAUSE");
}

class C size(28):
        +---
 0      | {vfptr}
 4      | {vbptr}
 8      | c1
        +---
12      | (vtordisp for vbase A)
        +--- (virtual base A)
16      | {vfptr}
20      | a1
24      | a2
        +---

C::$vftable@C@:
        | &C_meta
        |  0
 0      | &C::C2

C::$vbtable@:
 0      | -4
 1      | 12 (Cd(C+4)A)

C::$vftable@A@:
        | -16
 0      | &(vtordisp) C::A1
 1      | &A::A2

菱形继承   

 

#include <iostream>
using namespace std;

class A
{
public:
	A(int a1 = 0, int a2 = 0) {};
	~A() {};
	virtual void f() { cout << "A::f() " << endl; };
	virtual void af() { cout << "A::af() " << endl; };

protected:
	int a1;
	int a2;
};

class B1 : virtual public A
{
public:
B1(int a1 = 0, int a2 = 0, int b1 = 0) {};
~B1() {};
virtual void f() { cout << "B1::f() " << endl; };
virtual void f1() { cout << "B1::f1() " << endl; };
virtual void Bf1() { cout << "B1::Bf1() " << endl; };

protected:
int b1;
};

class B2 : virtual public A
{
public:
	B2(int b2 = 0) {};
	~B2() {};
	virtual void f() { cout << "B2::f() " << endl; };
	virtual void f2() { cout << "B2::f2() " << endl; };
	virtual void Bf2() { cout << "B2::Bf2() " << endl; };

protected:
	int b2;
};

class C : public B1, public B2
{
public:
	C(int a1 = 0, int a2 = 0, int b1 = 0, int b2 = 0, int c1 = 0) {};
	~C() {};
	virtual void f() { cout << "C::f() " << endl; };
	virtual void f1() { cout << "C::f1() " << endl; };
	virtual void f2() { cout << "C::f2() " << endl; };
	virtual void Cf() { cout << "C::Cf() " << endl; };

protected:
	int c1;
};


typedef void(*pfun)(); //函数指针
int main()
{
	C *cp = new C;
	pfun fun = NULL;

	cout << "B1的虚函数表" << endl;
	for (size_t i = 0; i < 3; i++)
	{
		fun = (pfun)*((long *)*(long*)cp + i);
		fun();
	}
	cout << "B2的虚函数表" << endl;
	long* p = (long*)cp + 3;
	for (size_t i = 0; i < 2; i++)
	{
		fun = (pfun)*((long *)*(long*)p + i);
		fun();
	}
	cout << "A的虚函数表" << endl;
	A* ap = (A*)((long*)cp + 8);
	for (size_t i = 0; i < 2; i++)
	{
		fun = (pfun)*((long *)*(long*)ap + i);
		fun();
	}
	system("PAUSE");
}

 

class C size(44):
        +---
 0      | +--- (base class B1)
 0      | | {vfptr}
 4      | | {vbptr}
 8      | | b1
        | +---
12      | +--- (base class B2)
12      | | {vfptr}
16      | | {vbptr}
20      | | b2
        | +---
24      | c1
        +---
28      | (vtordisp for vbase A)
        +--- (virtual base A)
32      | {vfptr}
36      | a1
40      | a2
        +---

C::$vftable@B1@:
        | &C_meta
        |  0
 0      | &C::f1
 1      | &B1::Bf1
 2      | &C::Cf

C::$vftable@B2@:
        | -12
 0      | &C::f2
 1      | &B2::Bf2

C::$vbtable@B1@:
 0      | -4
 1      | 28 (Cd(B1+4)A)

C::$vbtable@B2@:
 0      | -4
 1      | 16 (Cd(B2+4)A)

C::$vftable@A@:
        | -32
 0      | &(vtordisp) C::f
 1      | &A::af

 运行结果:

B1的虚函数表
C::f1()
B1::Bf1()
C::Cf()
B2的虚函数表
C::f2()
B2::Bf2()
A的虚函数表
C::f()
A::af()
请按任意键继续. . . 

参考文档:https://mp.weixin.qq.com/s/dTyAC2IQ50c9nmQGOC0c2A 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值