c++虛函數實現與this指標

來源:互聯網
上載者:User

標籤:分享   code   輸出   入口   blog   ima   不同   his   int   

我們知道當我們sizeof 一個類的時候,類的成員函數是不計算在對象的大小的裡的,這是為什麼呢?因為類的成員函數不是屬於某一個對象的,而是類的所有對象所共用的,就像static變數那樣。如果虛函數和普通成員函數一樣,那麼我們就不能通過指向子類的基類指標來引用子類的方法了,因為我們將不知道調用哪個方法,多態就無從談起。那麼多態是怎麼實現的呢?

  • 虛函數、虛指標與虛表

我們可以做一個小實驗

class A{public:        int a;        virtual void myfun(){}};class B:public A{public:        int b; };B obj_b;
obj_b.a=1;
obj_b.b=2;A *p=&B;cout<<p<<endl;cout<<&(p->a)<<endl;
cout<<p->a<<‘\t‘<<*(&(p->a)+1)<<endl;

p的值和&(p->a)的值是相差4個位元組的,最後一行輸出的值為1 ,2。我們可以推斷出obj_b在記憶體中的分布是首先一個佔有4位元組的某類型,然後是int a,最後是int b。

初始的4位元組其實就是虛指標。

而類A的對象在記憶體的分布其實是虛指標然後是int a。

如果類B繼承A,在B構造的時候,會繼承虛指標和int a,但是虛指標指向的虛表就不同了。若在B中實現了虛函數則虛表中的對應函數的入口地址也會改變。從而達到多態的目的。

注意指標p並訪問不到b,因為p是A類型的指標,可見指標的存取範圍由的類型決定了。所以我們通過&(p->a)+1來訪問b。

 

 

那麼多重繼承時是什麼情況呢?

多重繼承的時候,對於每個有虛函數的基類,子類都會繼承相應的虛指標並改寫虛表。

  • this指標

我覺得一篇blog寫的挺好就引用過來了。部落格地址為:http://www.cnblogs.com/CCQLegend/p/3270738.html

 

 

this指標跟不少人想象的不一樣,它的類型由被調用函數決定。它的類型遵循著這兩點規則:(途中打勾為首地址。)

1.對於非虛函數,this指標的基準地址為函數定義所在層級對象的首地址,範圍為該層級對象始末。

如:IA::FF();

this指標類型是以D0H為首地址,範圍是從首地址開始到DFH為止。(其實裡面有記憶體空洞,我們不去糾結這個)

Derived::FF();

this指標類型是C0H為首地址,範圍是從首地址到E8H為止。

2.對於虛函數,this指標的基準地址為函數首先聲明者的首地址,範圍為實現者的始末。

如:IA::F();

其this指標類型是以D0H為首地址,範圍是從首地址開始到DFH為止。

Derived::F();

其this指標類型是以D0H為首地址,範圍是從C0H到E8H為止。

那麼當有IA* a=new Derived();後,

a->F();便是這麼訪問b成員的了。假設首地址D0H儲存在寄存器rax裡,

rax-8

 

c++虛函數實現與this指標

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.