其實,這不是一個十分常見的問題,提問者應該已經對C++有了一定的瞭解。當然,我並不是說虛函數不能內聯的,比如有下面一個繼承體系:
class base
{
inline virtual void print();
};
void base::print()
{
fprintf("base\n");
}
class derived1 : public base
{
inline virtual void print();
};
void derived1::print()
{
fprintf("derived1\n");
}
int main()
{
base* p = new base;
derived1 d1;
(*p)->print(); //使用對象調用虛函數
p = &d1;
p->print(); //使用指針調用
}
其實,在編譯上面這段代碼的時候,編譯器將會遇到一個困惑,也就是p->print()這一句,我們知道,所謂內聯函數,其實也就相當於一個宏,編譯器將會用完整的函數代碼來替換這個調用,但是,對於p->print()來說,應該用哪個函數來替換呢?顯然,只能用基類base的print函數來替換,但,這卻違背了我們的本意,我們是要在運行時,動態的調用派生類的函數(這也就是所謂的多態),從而編譯器在遇到類似問題的時候,不得不忽略掉虛函數的內聯屬性,而暫時只保留一個接口(其實也就是虛函數指針),等到運行的時候,動態的加載相對應的函數。
我並不否認虛函數也同樣可以用inline來修飾,但你必須使用對象來調用,因爲對象是沒有所謂多態的,多態只面向行爲或者方法,但是C++編譯器,無法保證一個內聯的虛函數只會被對象調用,所以一般來說,編譯器將會忽略掉所有的虛函數的內聯屬性。