- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
一、多重继承,C继承自A和B
其类结构如下图(图2):
上面代码中主函数如为:
int _tmain(int argc, _TCHAR* argv[])
{
C* pc= new C; //pc=0x0046B3F0
A* pa= pc; //pa=0x0046B3F0
B* pb= pc; //pb=0x0046B3F0+8=0x0046B3F8
system(pause);
return 0;
}
对下面代码:
int _tmain(int argc, _TCHAR* argv[])
{
B b;//设B的地址为XXX
C* pc= ( C*)( b);//相当于C* pc= static_cast C*( b)。根据图2的类结构中C和B的位置关系
//(编译器可能认为B的地址比C的地址大8,所以C的地址为B的地址减去8),可知pc=XXX-8。此时可以想像出右边的类C
pc-VF();//错误。如正确,在(XXX-8)处获取虚表指针,但pc存放的是其他数据,故无法调用虚函数,产生错误。
system(pause);
return 0;
}
而下面代码却能正确执行:
int _tmain(int argc, _TCHAR* argv[])
{
A a;//设A的地址为XXX
C* pc= ( C*)( a);//相当于C* pc= static_cast C*( a)。根据图2的类结构中C和A的位置关系
//(相等),可知pc=XXX
pc-VF();//正确,有多态,调用的VF()为实际内存对象的函数,即调用A::VF()。在XXX处获取虚表指针,能正确调用虚函数VF()。
cout pc-m_i endl;//编译可通过,访问C:: m_i(其地址为XXX加上C::m_I相对于XXX的偏移量12,即XXX+12)但pc-m_i的值随机,
//因为此处内存并未被C对象使用或赋值,而可能是其他对象的内存空间。
system(pause);
return 0;
}
而如果B类中也有虚函数,如:
class A
{
public:
int m_i;
A(): m_i( 0{}
virtual void VF()
{
cout A::VF() endl;
}
};
class B
{
public:
int m_i;
B(): m_i( 0{}
virtual void VF()
{
cout B::VF() endl;
}
virtual void VG()
{
cout B::VG() endl;
}
};
class C: public A, public B
{
public:
int m_i;
C(): m_i( 0x99aabbcc){}
virtual void VF()
{
cout C::VF() endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
C* pc= new C;//设C的地址为XXX
pc-VF();//直接在XXX处的A虚表指针所指的虚表中找到C::VG()并调用C::VG()
pc-VG(); //因为VG()是B类中的,C类并未重写,所以先找到C类中B类起始地址(XXX+8),
//再在(XXX+8)处的B虚表指针所指的虚表中找到B::VG()并调用B::VG()。可以参照下面的反汇编代码。
B* pb= ( B*)( pc);//由下图3类结构知,pb=XXX+8,pb能访问内存大小为下图3中B部分的8字节(B虚表指针__vfptr和B数据成员B::m_i)
pb-VG();//直接在(XXX+8)处的B虚表指针所指的虚表中找到B::VG()并调用B::VG()
A* pa= ( A*)( pc);//由下图3类结构知,pa=XXX,pa能访问内存大小为下图3中A部分的8字节(A虚表指针__vfptr和A数据成员A::m_i)
pa-VF();//直接在XXX处的A虚表指针所指的虚表中找到C::VF()并调用C::VF()
system(pause);
return 0;
}
则类结构如图3:
反汇编代码如下:
pc-VF();
00D219E4 mov eax,dword ptr [pc]
00D219E7 mov edx,dword ptr [eax]
00D219E9 mov esi,esp
00D219EB mov ecx,dword ptr [pc]
00D219EE mov eax,dword pt
您可能关注的文档
最近下载
- 第3课+追求人生理想+第一框+第3目【中职专用】2024-2025学年中职思想政治《哲学与人生》(高教版2023基础模块).pptx VIP
- 2011年考研英语二真题及答案解析.pdf VIP
- 《建筑施工企业碳排放统计核算标准》.pdf
- 面向教学评价的情感分类.pptx VIP
- 人教A版必修第一册高中数学2.1等式性质与不等式性质【教学课件】.pptx VIP
- 《中药材炮制加工方法图解》.pdf VIP
- 小学残疾儿童送教上门教案(40篇).pdf VIP
- 羊群效应——一个班级最可怕的存在!--高一上学期班级凝聚力主题班会课件.pptx VIP
- Apple 环保系统操作说明FMD_Portal_TRM_Training.pdf
- 厄瓜多尔介绍PPT.pptx
文档评论(0)