C++11 override 和 final 關鍵字
C++11之前,一直沒有繼承控制關鍵字。禁用一個類的進一步衍生是可能的但也很棘手。為避免用戶在派生類中重載一個虛函數,你不得不向後考慮。
C++ 11添加了兩個繼承控制關鍵字:override和final。override確保在派生類中聲明的重載函數跟基類的虛函數有相同的簽名。final阻止類的進一步派生和虛函數的進一步重載。
虛函數重載
一個派生類可以重載在基類中聲明的成員函數,這是面向對象設計的基礎。然而像重載一個函數這麽簡單的操作也會出錯。關於重載虛函數的兩個常見錯誤如下:
無意中重載
簽名不匹配
首先,我們來分析一下無意中重載的綜合癥。你可能只是通過聲明了一個與基類的某個虛成員函數具有相同的名字和簽名的成員函數而無意中重載了這個虛函數。編譯器和讀代碼的人很難發現這個bug因為他們通常以為這個新函數是為了實現對基類函數的重載:
class A
{
public:
virtual void func();
};
class B: A{};
class F{};
class D: A, F
{
public:
void func();//meant to declare a new function but
//accidentally overrides A::func};
閱讀以上代碼,你不能確定成員函數D::func()是否故意重載了A::func().它也可能是個偶然發生的重載,因為兩個函數的參數列表和名字都碰巧一樣。
簽名不匹配是一個更為常見的情景。這導致意外創建一個新的虛函數(而不是重載一個已存在的虛函數),正如以下例子所示:
class G
{
public:
virtual void func(int);
};
class H: G
{
public:
virtual void func(double);
};
這種情況下,程序員本打算在類H中重載G::func()的。然而,由於H::func()擁有不同的簽名,結果創建了一個新的虛函數,而非對基類函數的重載:
H *p=new H;
p->func(5); //calls G::f
p->func(5.0); // calls H::f
碰到這種情況,不是所有的編譯器都會給個警告,有時那樣做會被設置成抑制這種警告。
基於上面的兩個錯誤
在C++11中,通過使用新關鍵字override可以消除這兩個bugs。override明確地表示一個函數是對基類中一個虛函數的重載
我們來看看override如何消除簽名不匹配bug的:
class G
{
public:
virtual void func(int);
};
class H: G
{
public:
virtual void func(double) override; //compilation error
};
當處理到H::func()聲明時,編譯器會 在一個基類查找與之匹配的虛函數。
final函數和類
C++11的關鍵字final有兩個用途。第一,它阻止了從類繼承;第二,阻止一個虛函數的重載。我們先來看看final類吧。
程序員常常在沒有意識到風險的情況下堅持從std::vector派生。在C++11中,無子類類型將被聲明為如下所示:
class TaskManager {/*..*/} final;
class PrioritizedTaskManager: public TaskManager {
}; //compilation error: base class TaskManager is final
同樣,你可以通過聲明它為final來禁止一個虛函數被進一步重載。如果一個派生類試圖重載一個final函數,編譯器就會報錯:
class A
{
pulic:
virtual void func() const;
};
class B: A
{
pulic:
void func() const override final; //OK
};
class C: B
{
pulic:
void func()const; //error, B::func is final
};
C::func()是否聲明為override沒關系,一旦一個虛函數被聲明為final,派生類不能再重載它。
轉自:http://www.cnblogs.com/minggong/p/6457726.html
C++11 override 和 final 關鍵字