2017-05-24 71 views
25

我讀一個真棒awesome C++11 tutorial和作者提供了這個例子,同時解釋final關鍵字:是否有意義最終關鍵字添加到虛擬功能在沒有基類的類(不派生)

struct B { 
    virtual void f() const final; // do not override 
    virtual void g(); 
}; 
struct D : B { 
    void f() const;  // error: D::f attempts to override final B::f 
    void g();  // OK 
}; 

那麼在這裏使用final關鍵字是否有意義?在我看來,你可以避免在這裏使用virtual關鍵字,並且防止f()被覆蓋。

+2

我不想敲它,因爲上師可能會出現並提出一個用例,它解決了一些非常模糊的編譯錯誤...但它看起來像一個愚蠢的事情。 – StoryTeller

+2

[有沒有將基類函數標記爲virtual和final的意義?](https://stackoverflow.com/questions/16739135/is-there-any-sense-in-marking-a-base -class-function-as-both-virtual-and-final) –

+0

實際上還有更多的重複,例如[最終虛擬函數有什麼意義?](https://stackoverflow.com/questions/11704406/) – Ruslan

回答

32

如果您沒有將函數標記爲virtualfinal那麼子類仍然可以實現該函數並隱藏基類函數。

通過使功能virtualfinal子級別不能覆蓋隱藏功能。

+2

我知道一個古茹會來。儘管我認爲這在開銷方面有點太過分了(可能會或可能不會被忽略),只是爲了防止隱藏。 +1。 – StoryTeller

+2

很明顯,在這個問題上已經達成了共識,但是我爲了一個人想要解釋如何不做任何有用的*和*打破另一種語言功能將被視爲一種好處。 – Quentin

+1

@Quentin消除了模糊的可能性,例如在模板的情況下void doStuff(DerivedFromB&b){b.f(); }',你可以100%確定'f()'調用去哪裏 – Caleth

2

你的直覺是正確的:使功能virtual只能立即用final來限制它對非虛函數沒有任何好處。這只是一個簡短的示例代碼片段來演示該功能。

此外,在其他的答案中描述,這實際上打破了功能隱藏 - 你將永遠不會成爲能夠有一個f功能具有相同的參數列表中D或任何派生類的。
當您決定在模型中限制f時,這是一個權衡。由於無法在此處執行實際的虛擬呼叫,因此您基本上有缺點,沒有任何好處。

+1

我想到隱藏名字。因此,您可以防止派生類隱藏f()。如果你聲明沒有virtual關鍵字的f(),我猜可以隱藏在派生類中。 –

+0

與往常一樣,評論與downvotes相得益彰。 – Quentin

+1

我認爲downvotes是由於你對禁用名稱隱藏的態度。我想這個功能實際上可以用於某些特殊用途,但我不能說出任何這樣的目的。 – Ruslan

11

是的!在您提供的示例中,final關鍵字可以防止任何派生類重寫f(),正如您所說的那樣。如果函數是非虛擬,D:f()允許隱藏函數的基類版本:

struct B { 
    void f() const; // do not override 
    virtual void g(); 
}; 
struct D : B { 
    void f() const; // OK! 
    void g();  // OK 
}; 

通過使f()一個virtualfinal功能,任何試圖在覆蓋或隱藏導致編譯錯誤。

相關問題