c 類內部函式呼叫虛函式

2022-09-16 21:21:23 字數 1656 閱讀 3669

做專案的過程中,碰到乙個問題。

問題可以抽象為下面的問題:

普通人吃飯拿筷子,小孩吃飯拿勺子。

class

people

virtual

void

get_util_to_eat()

};class children : public

people

};int

main()

輸出結果:

children get scoop

當然這也符合我們的預期。

因為people不是虛函式,所以上述程式呼叫的是people中的eat方法,這就涉及到乙個之前我一直模糊的概念,在乙個類方法中呼叫虛方法,是如何呼叫的。

這又涉及到之前不得不說的乙個問題:

class

a };

intmain()

上述**會輸出什麼,按照直觀的感覺null怎麼可能呼叫方法呢,要出core吧。

但是事實上,輸出的是:

i am a

呼叫類函式的時候,c++編譯器並不會管該類是否為空,而是將該類的位址當做this指標傳到函式中去。

a->print() 時,在編譯器中就相當於print(a)

有因為print中沒有用到成員變數的情況,所以自然能很正確的執行。

然後來看下彙編**就能更理解了。以下是people類內的彙編**。

21

void

eat() {

0x0000000000400bd2

<+0>: push %rbp

0x0000000000400bd3

<+1>: mov %rsp,%rbp

0x0000000000400bd6

<+4>: sub $0x10,%rsp

0x0000000000400bda

<+8>: mov %rdi,-0x8(%rbp) //rsp表示第乙個引數,也就是類的指標

get_util_to_eat();

0x0000000000400be9

<+23>: mov -0x8(%rbp),%rax //將類指標放入rax暫存器中

0x0000000000400bed

<+27>: mov (%rax),%rax //取首位址值,也就是虛表位址

0x0000000000400bf0

<+30>: mov -0x8(%rbp),%rdi //放入rdi中,下次函式呼叫的時候取參用

0x0000000000400bf4

<+34>: mov (%rax),%rax //取出虛表中函式的位址

0x0000000000400bf7

<+37>: callq *%rax //呼叫改函式

總結就是,進入類的非靜態成員函式時,會預設攜帶類的指標(this),然後改函式內用到成員變數、成員方法都等同於在前面加了乙個this->

so 回到最初的那個問題,在people::eat中傳入的是chilren的指標,所以呼叫 get_util_to_eat 時從虛表中取出了children::get_util_to_eat方法並進行呼叫。

手撕虛函式,虛函式呼叫虛函式

乙個類的記憶體分布,虛函式表指標,普通成員變數,sizeof a 為乙個虛表指標 32位是4位元組 普通成員變數 靜態什麼的都不是 虛函式本身也是函式,相當於乙個指標,虛函式表裡面含有虛函式,相當於乙個二級指標,虛函式表指標指向虛函式表,相當於乙個 指標,所有可以通過乙個 指標直接訪問某個虛函式。見...

C 建構函式中呼叫虛函式

我們知道 c 中的多型使得可以根據物件的真實型別 動態型別 呼叫不同的虛函式。這種呼叫都是物件已經構建完成的情況。那如果在建構函式中呼叫虛函式,會怎麼樣呢?有這麼一段 class a virtual void func void test public int m ival class b publ...

C 建構函式中呼叫虛函式

談談關於建構函式中呼叫虛函式的情況,僅討論單繼承,不考慮虛擬繼承和多重繼承。測試平台 vs2013 win7x64 乙個例子 include include class base public virtual void func class deri public base public virtu...