前面兩篇文章我相信大家反複讀了之後對這節不陌生了:
首先來看代碼:
class Demo{public: //靜态成員變量 static const int sx = 0; //靜态函數 static void SF1(){ }public: //成員變量 int x;public: //成員函數 void F1(){ cout << "I'm from Demo::F1()" << endl; } void F2(){ cout << "I'm from Demo::F1()" << endl; } virtual void F3(){ cout << "virtual F3()" << endl; }public: //構造函數,C++文法不允許擷取構造函數和析構函數位址,要分析其位址,隻能檢視生産的彙編代碼了。 Demo() { } //析構函數 ~Demo() { }}; typedef void (Demo::*Func)(); typedef void(*func)();union{ Func f; void *addr;}ut;int main(int argc, char** argv){ int i = 0; cout << "main()函數的位址是 :" << std::hex << std::showbase << main << endl; ut.f = &Demo::F1; cout << "成員函數F1()的位址是 :" << std::hex << std::showbase << ut.addr << endl; ut.f = &Demo::F2; cout << "成員函數F2()的位址是 :" << std::hex << std::showbase << ut.addr << endl; cout << "靜态成員函數SF1()的位址是:" << std::hex << std::showbase << Demo::SF1 << endl; cout << "靜态成員變量sx的位址是 :" << std::hex << std::showbase << &Demo::sx << endl; cout << "Demo類型執行個體的大小 :" << sizeof(Demo) << endl; Demo* pObj = new Demo(); cout << "對象指針變量的位址是 :" << std::hex << std::showbase << &pObj << endl; cout << "建立對象的位址是 :" << std::hex << std::showbase << pObj << endl; cout << "成員變量的位址是 :" << std::hex << std::showbase << &pObj->x << endl; cout << "虛函數表的入口位址 :" << std::hex << std::showbase << pObj << endl; cout << "虛函數表F3的位址:"<< (int*)*(int*)(pObj) <<endl; return 0;}
這段代碼的運作結果如下:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SZhRGNyATY4QTM2I2MxITYzIjY4YDMwI2MwUWM3ETO48CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
這裡要指出的是大家可以看到靜态成員函數和靜态成員變量sx的位址都是0x00007FF開頭的,實際上他們都在全局資料區域存儲(全局變量,靜态變量),如果你有耐心,可以斷點檢視下棧空間内的局部變量i的位址:
你會發現棧空間的位址和全局資料區的位址都不一樣,這樣你也了解了虛函數表的空間。
這樣看這張圖,你就知道哪些變量在哪裡存儲了。
如果我們修改對象構造的方式,通過在棧上構造一個對象,
int main(int argc, char** argv){ Demo pObj; cout << "建立對象的位址是 :" << std::hex << std::showbase << &pObj << endl; cout << "成員變量的位址是 :" << std::hex << std::showbase << &pObj.x << endl; cout << "靜态成員函數SF1()的位址是:" << std::hex << std::showbase << Demo::SF1 << endl; cout << "靜态成員變量sx的位址是 :" << std::hex << std::showbase << &Demo::sx << endl; ut.f = &Demo::F1; cout << "成員函數F1()的位址是 :" << std::hex << std::showbase << ut.addr << endl; ut.f = &Demo::F2; cout << "成員函數F2()的位址是 :" << std::hex << std::showbase << ut.addr << endl; cout << "虛函數表的入口位址 :" << std::hex << std::showbase << &pObj << endl; cout << "虛函數表F3的位址:"<< (int*)*(int*)(&pObj) <<endl; return 0;}
我想你現在根據剛才列印的成員變量,成員函數,虛函數表位址已經可以自己畫出類成員的記憶體布局了。