2013-05-29 17 views
19

我讀comments上香草薩特的大師周終極版約virtual功能,終於看見他提這一點:使用情況進行最後類

[...]「最終的用途是罕見」 - 好吧,他們有點。我不知道很多,在標準化過程中,Bjarne一再要求提供它解決的問題的例子,並指出應該使用它的模式,我不記得任何突出的主要問題。我唯一知道的是,如果你定義了一個庫模塊(這還不是一個標準概念),那麼使葉類最終可以給編譯器提供更多的信息來虛擬化調用,因爲知道庫之外的代碼贏得'進一步推導出來,但我不確定這些日子在整個程序優化(包括積極的虛擬化)的情況下有多重要。

這個答案不提供有關使用情況final類上很多例子,我會有興趣知道什麼問題,它可以真正解決。你知道任何,或將final上課只成爲一些模糊和幾乎未使用的功能?

+4

相關博客文章[here](http://akrzemi1.wordpress.com/2012/09/30/why-make-your-classes -最後/)。 – juanchopanza

+0

相關問題:http://stackoverflow.com/questions/8824587/purpose-of-the-final-keyword – Alex

+0

也相關:http://stackoverflow.com/questions/11704406/whats-the-point-of-a -final-virtual-function?rq = 1 – Alex

回答

6

我發現了一個有趣的異常用例,我描述了here。簡而言之,通過防止類似int類的繼承,您可以爲自己購買一種可能性,以便在未來版本的庫中使用內置類型替換它,而不會有破壞用戶代碼的風險。

但是更常見的例子是虛擬化。如果您將類標記爲final,則編譯器可以應用某些運行時優化。例如,

struct Object { 
    virtual void run() = 0; 
    virtual ~Object() {} 
}; 

struct Impl final : Object 
{ 
    void run() override {} 
}; 

void fun(Impl & i) 
{ 
    i.run(); // inlined! 
} 

i.run()呼叫現在可以內聯由於final符。編譯器知道不需要vtable查找。

+0

那麼,我剛纔說上述鏈接已經在評論中分享了,但是我沒有意識到這也是你自己的文章。 – Morwenn

0

final當您爲初始界面提供(某種)外觀時可能會很有用,該界面更易於被子類使用。 考慮:

class IMovable { 
    public: 
    void GoTo(unsigned position) = 0; 
} 

class Stepper : public IMovable { 
    public: 
    void GoTo(unsigned position) final; 
    protected: 
    virtual void MoveLeft() = 0; 
    virtual void MoveRight() = 0; 
} 

void Stepper::GoTo(unsigned position) { 
    for(;current_pos < position; current_pos++) { 
    MoveRight(); 
    } 
    for(;current_pos > position; current_pos--) { 
    MoveLeft(); 
    } 
}  

現在,如果你想從你看,你應該重寫MoveRightMoveLeft步進推導,但你不應該重寫GoTo

在這個小例子中很明顯,但是如果IMovable有20個方法,Stepper有25個,並且有默認實現,那麼你可能很難弄清楚你應該什麼以及不應該重寫什麼。我在硬件相關的庫中遇到過這樣的情況。但我不會稱這是一個值得標準推崇的主要問題;)

+1

那是不宣佈'類'決賽! – Alex

+0

@Alex,你是對的。我的眼睛吸引了一個關於虛擬功能的短語,所以我錯過了強調讓課程成爲最終的功能,而不是功能。 親愛的OP,我應該收回答案還是對最終功能感興趣? – Steed

+0

@定價我很抱歉,但我對'最後'功能根本不感興趣;在問這個問題之前,我已經知道他們爲什麼存在了^^「 – Morwenn

相關問題