类的多个继承

先看一段代码

#include<stdio.h>
class A
{
public:
	virtual void PrintA()
	{
		printf("A\n");
	};
	virtual void PrintAA()
	{
		printf("AA\n");
	};
};
class B
{
public:
	virtual void PrintB()
	{
		printf("B\n");
	}
};
class C:public A,public B
{
//	int a;
public:
	virtual void PrintA()
	{
		printf("CA\n");
	};
	virtual void PrintB()
	{
		printf("CB\n");
	}


};
void main()
{
	C *c = new C;
	printf("%d",sizeof(C));//打印为8
	A *a = c;
	B *b = c;
	printf("A:%d B:%d C:%d\n",a,b,c); //5648160 5648164 5648160 (10进制显示)
        b->PrintB(); //CB

	a->PrintA();//CA
	a->PrintAA();//AA
}

看一下汇编代码

.text:0040F03B                 mov     ecx, [ebp+var_28]
.text:0040F03E                 mov     [ebp+var_18], ecx
.text:0040F041                 mov     edx, [ebp+var_18]
.text:0040F044                 mov     eax, [edx]
.text:0040F046                 mov     esi, esp
.text:0040F048                 mov     ecx, [ebp+var_18]
.text:0040F04B                 call    dword ptr [eax]//     b->PrintB()
.text:0040F04D                 cmp     esi, esp
.text:0040F04F                 call    __chkesp
.text:0040F054                 mov     ecx, [ebp+var_14]
.text:0040F057                 mov     edx, [ecx]
.text:0040F059                 mov     esi, esp
.text:0040F05B                 mov     ecx, [ebp+var_14]
.text:0040F05E                 call    dword ptr [edx]      //a->PrintA()
.text:0040F060                 cmp     esi, esp
.text:0040F062                 call    __chkesp
.text:0040F067                 mov     eax, [ebp+var_14]
.text:0040F06A                 mov     edx, [eax]
.text:0040F06C                 mov     esi, esp
.text:0040F06E                 mov     ecx, [ebp+var_14]
.text:0040F071                 call    dword ptr [edx+4]  //a->PrintAA()
.text:0040F074                 cmp     esi, esp
.text:0040F076                 call    __chkesp
.text:0040F07B                 mov     ecx, [ebp+var_C]
.text:0040F07E                 mov     large fs:0, ecx
.text:0040F085                 pop     edi
.text:0040F086                 pop     esi
.text:0040F087                 pop     ebx
.text:0040F088                 add     esp, 68h
.text:0040F08B                 cmp     ebp, esp
.text:0040F08D                 call    __chkesp
.text:0040F092                 mov     esp, ebp
.text:0040F094                 pop     ebp
.text:0040F095                 retn
.text:0040F095 _main           endp


先看一下大小,如果C只有一个基类,那它的大小就是4,上一次,说明了。而这有两个基类,那它为什么是8。很明显,由于A,B都有虚函数,所以,在C是其实有两个虚表。

看看打印,printf("A:%d B:%d C:%d\n",a,b,c);A: 5648160 B:5648164 C:5648160,而为什么a,b不一样。这会和虚表有关。

    A *a = c;
    B *b = c;

这两句代码并不是简单的将c的值给a,b。而是编译器内部处理了。

相当于

a  = c

b = c + 4 //4 是sizeof(A)

为什么是b是加4,class C:public A,public B.这就是原因

所以调用Print 时,以下是,(只是简单的解释,不能编译的)

call [(DWORD*)a[0]][0] //   a->PrintA();

call [(DWORD*)a[0]][1] //   a->PrintAA();

call [(DWORD*)b[0]][0] //   b->PrintB();


总结一下:

class A

{

    PVOID *vftable_A ;

}

class B

{

    PVOID *vftable_B ;

}

class C:public A,public B

{

   PVOID *vftable_C_FRO_A;

   PVOID *vftable_C_FRO_B;

}










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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值