內聯函數可以是虛函數嗎?

為了弄清內聯函數能不能是虛函數我做了個實驗。

首先,我知道內不內聯可能最終是編譯器說了算,寫了inline不一定是,不寫也不一定不是,但是大部分情況還是由你決定。

內聯函數從原則上講不能是虛函數,內聯在編譯器完成,而虛函數在執行時綁定,這可能是大部分人找到的答案。但是我還是想實驗一下。

我這麼寫的代碼:(和final沒有關係,我這裡做的是另一個實驗,忽略final)

我用g++ -std=c++14 -S 命令得到彙編之後的結果:

可以看到#89是在調用基類的函數,而不是直接把代碼粘到這兒。想請大家幫我看看,內聯函數可以是虛函數是什麼意思,是能不能寫成inline型,還是編譯器認不認可這個inline?程序編譯執行都沒有問題,沒錯誤沒警告。


可以。

當使用非多態調用時,編譯器可選擇內聯,例如:

#include &

struct Base {
virtual ~Base() {}
virtual void Foo() { printf("Base::Foo()
"); }
};

struct Derived : Base {
virtual void Foo() { printf("Derived::Foo()
"); }
};

Base* b = new Derived; // 非 static 令編譯器不能在編譯期知道 b 指向那個類型的對像

int main() {
b-&>Foo(); // 不可能內聯
b-&>Base::Foo(); // 非多態調用,可以內聯(但具體是否內聯由編譯器決定)
delete b;
}

許多時候,派生類的虛函數會調用基類的同名函數,這時候不是多態調用,可以內聯。


如果虛函數通過對象被調用,倒是可以inlined,但大部分虛函數調用動作是通過對象的指針或引用完成的,此類行為無法被inlined。

inlined意味著編譯期將調用端的調用動作被函數本體取代,若無法知道哪個函數該被調用時,編譯器沒法將該函數加以inlining。 (more effective C++ )


要多態的時候不內聯,不多態的時候(也就是非指針、引用,也就是傳值)可以內聯,不矛盾丫


謝邀,inline virtual確實有碰到過,題主說的對,無論顯式還是隱式,inline都只是一個申請,最終由編譯器決定內聯還是不內聯(是否大部分情況由你決定這個要看你怎麼理解這句話了,個人覺得還是表達為由編譯器按場景來決定比較合適)。

編譯器覺得適合inline那就內聯咯,不適合就不內聯咯(當我沒說)。具體點,先說不適合內聯的情況,1,編譯器會保證多態性,但是多態的時候就不會內聯,題主已經說了理由了,編譯器跟運行期的分歧,所以如果場景裡面需要使用inline virtual函數的多態性,那就不會內聯了;2,其他不適合內聯的情況,例如通過函數指針來調用內聯函數。

所以我的結論是,可以那樣寫,但具體內聯不內聯,看具體的調用情況由編譯器來決定是否內聯。如有錯誤請輕拍。


推薦閱讀:

請問mono unity Xamarin 這三者之間是什麼關係?
初學者學編程,是看項目源碼學習,還是看著書一步步敲代碼見效?
詳細介紹一下python和matplotlib,ipython的安裝使用方法?
Python for 循環中 in 關鍵字含義是什麼?
如何學習遞歸呢?

TAG:編程語言 | C | 虛函數C |