为了验证前面提到过的类型动态转换(即dynamic_cast转换),以及对象类型的强制转换。我们利用前面定义的C041、C042及C082类来进行验证。
运行下列代码:
c082.C041::c_ = 0x05;
PRINT_VTABLE_ITEM(c041, 0, 0)
PRINT_DETAIL(C041, ((C041)c082))
PRINT_VTABLE_ITEM(((C041)c082), 0, 0)
PRINT_VTABLE_ITEM(c082, 5, 0)
C042 * pt = dynamic_cast<C042*>(&c082);
PRINT_VTABLE_ITEM(*pt, 0, 0)
第2行和第5行是为了对照方便而打印原对象中的信息。第3、4行把C082对象类型进行强制转换并分别打印转换后的对象内存信息及虚表信息。第6行我们用dynamic_cast进行了一次动态类型转换,从子类的指针转型为右父类的指针,再把指针指向的对象的信息打印出来。
结果为:
c041 : objadr:0012FA74 vpadr:0012FA74 vtadr:0045B364 vtival(0):0041DF1E
The detail of C041 is 64 b3 45 00 05
((C041)c082) : objadr:0012F2A3 vpadr:0012F2A3 vtadr:0045B364 vtival(0):0041DF1E
c082 : objadr:0012FA50 vpadr:0012FA55 vtadr:0045B36C vtival(0):0041D483
*pt : objadr:0012FA55 vpadr:0012FA55 vtadr:0045B36C vtival(0):0041D483
首先我们比较最后两行,从objadr列我们可以知道pt指向的并不是c082对象的起始地址,而是指向了c082的第2个虚表指针的所在地址(因为最后一行的objadr值等于倒数第2行的vpadr的值)。倒数第二行的vpadr值是c082对象的第2个虚表指针(我们在输出时指定了偏移值5)。而这个地址正是c082对象中属于从C042类继承而来的部分,即在进行动态类型转换时,除了改变类型信息,编译器还调整了指针的位置,以确保转换语义的正确性。所以我们可以知道,对指向有复杂继承结构的类对象的指针进行类型转换(一般在继承树中向上或向下转换)时,必须使用dynamic_cast,它会正确的处理指针位置的调整,如果转换是非法的,它会返回一个NULL指针。使用dynamic_cast时记得要做这个检查,文中为了简略把这些检查省去了。这种检查可以通过宏来定义,以便于在release版中去掉,提高效率。
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!