標籤:
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進行了強制類型轉換,但是不會糾正虛表。
執行個體解析C++虛表