在設計類時,虛函數著重體現基類或介面的設計原則。虛函數應能表達你所想要表達的,使得衍生類別在重載是不存在歧義。虛函數存在以下用法:
1、虛解構函式
虛解構函式表示本類為抽象基類,使用者可以從本類派生,使用者也可通過基類對象管理衍生類別對象。public的虛解構函式比較常用,表示使用者可以管理對象的生命期。protected的虛解構函式表示使用者只能通過本對象使用衍生類別對象,但不包括生命期管理。private的虛解構函式極少使用。
一個常見的錯誤是將介面的解構函式定義為public的虛解構函式。我個人不是很贊同這一點,他混淆了抽象對象和介面的本質區別,抽象對象表示衍生類別是基類的一種,如猴子是動物的一種,這種特性是運行時不可變更的,所以一般體現為單繼承。而介面表示一個具有某種特徵或者角色的對象,這種特性可以在運行時改變,所以一般體現為多繼承。如某個人既有老師角色也有學生角色,四年以後,他的學生角色可能沒有了,但該對象依然存在,所以對象的生命期不應該通過介面來管理,只能通過抽象基類來管理。所以介面的解構函式應體現為保護的非虛解構函式。執行個體如下:
class CAnimate
{
public:
...
virtual ~CAnimate(void){}
...
};
class IStudent
{
...
protected:
~IStudent(void){}
};
2、public的虛函數
public的虛函數體現了抽象類別或介面的本質,即體現抽象類別或介面的不變式。這是虛函數使用最廣泛的方式,然而我個人並不贊同抽象類別的public虛函數,應為它使得衍生類別的重載實現引入了一定的歧義。執行個體如下:
class CAnimate
{
public:
virtual void DoSomething(void);
...
};
class CBird : public CAnimate
{
public:
virtual void DoSomething(void)
{
....
CAnimate::DoSomething(); //要不要調用基類的實現呢? 不知道,模糊中
}
};
所以代之以如下:
class CAnimate
{
public:
void DoSomething(void) {DoSomethingImp()l}
protected:
virtual void DoSomethingImp(void);
};
class CBird : public CAnimate
{
protected:
virtual void DoSomethingImp(void)
{
....
CAnimate::DoSomethingImp(); //必須要調用基類的實現, 保護的虛函數正是表示衍生類別和基類合作完成一件事
}
};
2、protected虛函數
保護的虛函數表衍生類別和基類合作完成一件事,在衍生類別的實現中必須調用基類的實現。當然是採用前調用還是後調用依然比較模糊。
3、private虛函數
私人的虛函數表示要麼是衍生類別完成一件事,要麼是基類完成,但不能共同完成。
胡樂秋
2010/9/6
http://blog.csdn.net/hlqyq