多態(Polymorphism)是面向對象程序設計最重要的特性之一。C++ 通過結合虛函數和指針(引用)來實現多態。作為 C++ 用戶,你當然知道如何將虛函數和指針(引用)結合起來以實現多態。但在這些概念之間,可能還存在些許模糊地帶。例如說,你有思考過下面這個問題嗎?
純虛函數能有實現嗎?此篇討論 C++ 中虛函數的聲明與定義。
直接回答問題
能!純虛函數可以有定義,並且有時我們必須給出純虛函數的定義。不過有一點需要注意:和其它成員函數不同,純虛函數的定義必須實現在類定義之外。(見下例)
虛成員函數
我們首先來看看關於虛成員函數生命和定義的一些規則。根據 C++ 標準,虛成員函數應在類定義中生命,且必須有定義(實現)。注意,在類定義外實現虛成員函數時,不能再加 virtual 關鍵字。
不過,C++ 標準沒有要求必須在編譯期對這條規則進行診斷。也就是說,如果沒有給出虛成員函數的實現,編譯器可能不會報錯。不過,鏈接器可能會提示引用了未定義的符號這樣的錯誤。
純虛成員函數
純虛函數使類成為「抽象類」。具體來說,我們不能創建抽象類類型的對象,也不能將其作為函數的參數類型、返回類型,也不能作為顯式類型轉換的目標類型。
因此,我們永遠不會有機會調用抽象類中的徐成員函數。另一方面,純虛函數必然會在派生類中被複寫。因此,在大多數情況下,純虛函數的實現是沒什麼用處的。也因此,我們可以將一個成員函數聲明為純虛的,但是不給它的定義。
也就是說,對於純虛函數,我們可以:
- 在類定義中聲明純虛函數,並且不給實現;
- 在類定義中聲明純虛函數,並且在類定義之外給出實現。
不過,這裡有兩處例外:
- 對於純虛析構函數,必須提供實現。
- 派生類中的成員函數可以調用抽象類中的純虛函數,但必須加上抽象類的限定符(Base::some_pure_virtual_function())。
在這兩種情況下,提供純虛函數的定義是有意義的——也必須提供。
閱讀更多 波波桑 的文章