當一個函數是內聯和虛函數時,會發生代碼替換或使用虛表調用嗎? 為了弄 清楚內聯和虛函數,讓我們將它們分開來考慮。通常,一個內嵌函式是被展開的 。
class CFoo {
private:
int val;
public:
int GetVal() { return val; }
int SetVal(int v) { return val=v; }
};
這裡,如果使用下列代碼:
CFoo x;
x.SetVal(17);
int y = x.GetVal();
那麼編譯器產生的目標代碼將與下面的程式碼片段一樣:
CFoo x;
x.val = 17;
int y = x.val;
你當然不能這麼做,因為val是個私人變數。內嵌函式的優點是不用函數調用 就能隱藏資料,僅此而已。
虛函數有多態性,意味著派生的類能實現相同的函數,但功能卻不同。假設 GetVal 被聲明為虛函數,並且你有第二個 以不同方法實現的類 CFoo2:
class CFoo2 : public CFoo {
public:
// virtual in base class too!
virtual int CFoo2::GetVal() {return someOtherVal;}
};
如果 pFoo是一個 CFoo 或 CFoo2 指標,那麼,無論 pFoo 指向哪個類 CFoo 或 CFoo2,成員函數 pFoo->GetVal 都能調用成功。
如果一個函數既是虛擬函數,又是內嵌函式,會是什麼情況呢?記住,有兩 種方式建立內嵌函式,
第一種是在函數定義中使用關鍵字 inline,如:
inline CFoo::GetVal() { return val; }
第二種是在類的聲明中編寫函數體 ,就象前面的 CFoo2::GetVal 一樣。所以如果將虛函數體包含在類的聲明中, 如:
class CFoo {
public:
virtual int GetVal() { return val; }
};