1. 程式人生 > 其它 >C++ Virtual詳解

C++ Virtual詳解

Virtual是C++ OO機制中很重要的一個關鍵字。只要是學過C++的人都知道在類Base中加了Virtual關鍵字的函式就是虛擬函式(例如函式print),於是在Base的派生類Derived中就可以通過重寫虛擬函式來實現對基類虛擬函式的覆蓋。當基類Base的指標point指向派生類Derived的物件時,對point的print函式的呼叫實際上是呼叫了Derived的print函式而不是Base的print函式。這是面向物件中的多型性的體現。(關於虛擬機制是如何實現的,參見Inside the C++ Object Model ,Addison Wesley 1996)

class Base
{
public:Base(){} public: virtual void print(){cout<<"Base";} }; class Derived:public Base { public:Derived(){} public: void print(){cout<<"Derived";} }; int main() { Base *point=new Derived(); point->print(); }

Output:
Derived
這也許會使人聯想到函式的過載,但稍加對比就會發現兩者是完全不同的:
(1) 過載的幾個函式必須在同一個類中;
覆蓋的函式必須在有繼承關係的不同的類中
(2) 覆蓋的幾個函式必須函式名、引數、返回值都相同;
過載的函式必須函式名相同,引數不同。引數不同的目的就是為了在函式呼叫的時候編譯器能夠通過引數來判斷程式是在呼叫的哪個函式。這也就很自然地解釋了為什麼函式不能通過返回值不同來過載,因為程式在呼叫函式時很有可能不關心返回值,編譯器就無法從程式碼中看出程式在呼叫的是哪個函數了。
(3) 覆蓋的函式前必須加關鍵字Virtual;
過載和Virtual沒有任何瓜葛,加不加都不影響過載的運作。

關於C++的隱藏規則:
我曾經聽說過C++的隱藏規則:
(1)如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual
關鍵字,基類的函式將被隱藏(注意別與過載混淆)。
(2)如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual
關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)。