OS:Windows 7
关键字:VS2012,C++,VTable,虚表
1.创建一个Win32控制台应用程序代码如下:
#include "stdafx.h" #include <string> #include <iostream> class A { public: virtual std::string AName(){return "A";} }; class B { public: virtual std::string BName(){return "B";} }; class C : public A, public B { public: virtual std::string BName(){return "C";} }; int _tmain(int argc, _TCHAR* argv[]) { C* pC = new C(); C* pC1 = new C(); std::cout<<pC->BName()<<std::endl; B* pB = static_cast<B*>(pC); std::cout<<pB->BName()<<std::endl; //A* pA = static_cast<A*>(pB); A* pA = dynamic_cast<A*>(pB); std::cout<<pA->AName()<<std::endl; A* pA1 = reinterpret_cast<A*>(pB); std::cout<<pA1->AName()<<std::endl; return 0; }
2.编译运行,控制台输出结果如下:
C
C
A
C
看到这个结果有没有让你奇怪的地方?为什么“pA1->AName()”输出是C?
3.在Watch窗口里看到的虚表结构如下:
总结如下:
- pC和pC1是类C的两个实例指针,这两个实例的虚表是一样的,也就是说虚表是属于类的,一个类有一个虚表。
- 因为类C重写了类B的BName函数,所以C的虚表里存的是C::BName
- “A* pA = static_cast<A*>(pB);”是编译不通过的,因为A和B是不相关的两个类,也就是没有继承关系。
- “A* pA = dynamic_cast<A*>(pB);”是可以的,因为dynamic_cast会在运行时进行类型检查,dynamic_cast是最安全的,但是效率最低。
- “A* pA1 = reinterpret_cast<A*>(pB);”是可以编译通过了,但是运行时会有意想不到的结果。reinterpret_cast进行了强制类型转换,但是不会纠正虚表。
时间: 2024-10-21 15:21:45