2017-09-27 162 views
41

例如:重寫純虛函數時,有沒有使用`override`的意思?

class Base { 
    virtual void my_function() = 0; 
}; 

class Derived : Base { 
    void my_function() override; 
}; 

從我讀的override關鍵字用來確保我們有在我們覆蓋的功能正確的簽名,這似乎是其唯一的用途。

然而,在一個純虛函數的情況下,編譯器會如果我們在派生類中使用了不正確的簽名(或基類,這取決於一個人如何看待事物)拋出一個錯誤。那麼,Derived::my_function()聲明的末尾是否還有點加override

+4

請注意,抽象*傳播*。如果你在'Derived'類中提供了錯誤的簽名,那麼'Derived'類也變得很抽象。如果沒有'override'關鍵字,可能無法在正確的位置檢測到。 –

+4

它確保如果基類與「override」斷言不兼容,您的代碼將無法編譯。 – EJP

+1

「penning有針對性的教學程序傳播優先編程實踐」 - T.J.Elgan – coderatchet

回答

67

However, in the case of a pure virtual function, the compiler would throw an error if we used an incorrect signature in the Derived class

不,這編譯:

class Base { 
    virtual void my_function() = 0; 
}; 

class Derived : Base { 
    void my_function(int); 
//     ^^^ mistake! 
}; 

雖然這並不:

class Base { 
    virtual void my_function() = 0; 
}; 

class Derived : Base { 
    void my_function(int) override; 
}; 

error: void Derived::my_function(int) marked override , but does not override


你在談論只有實例Derived時出現的錯誤 - override允許y ou早點發現錯誤,並使得定義更清晰/更具可讀性。

+0

您可以將運行時錯誤添加到另一個類中,並在保留純虛擬的同時實現'Base :: my_function'。 – Yakk

+3

等等,所以有一個點?你繼續談論它是如何有用的,但只是從「不」開始。 – snb

+10

「否」是爲了響應編譯器拋出錯誤的聲明。 –

30

是的,這是堅持用override關鍵字作爲一個防禦性的做法是一個好主意。

Base的作者確定my_function不再是純虛擬的時候,應考慮進行重新設計,並且應該採用新的參數。使用override,編譯器會捕獲這個問題;沒有override你的Derived類將繼續編譯。

7

是!

它提高代碼清晰度override關鍵字防止模糊和傳送它的覆蓋它的基類的方法的意義。

防止可能出現的意外的使用: 在將來,如果基類變化方法簽名(這裏virtual),它迫使派生類來相應地改變。 (帶有編譯器錯誤)。否則(不帶override關鍵字)可能會被視爲method overload,這不是預期的。

+0

雖然它不會因爲正常隱藏而導致方法過載 – RiaD

3

通常不與override煩心事就在移動的錯誤。我發現更好地獲取錯誤的位置 - 在定義無法覆蓋的方法時,而不是在實例化類時。

但是,有這個防止運行時錯誤的方式。

struct Base { 
    virtual void foo(int x = 0) = 0; 

    void foo(double d) { 
     foo((int)d); 
    } 
}; 
inline void Base::foo(int x) { std::cout << "Default foo(" << x << ")\n"; } 

struct Derived:Base { 
    using Base::foo; 
    virtual void foo() { // oops, no int! 
    std::cout << "Derived::foo()\n"; 
    Base::foo(); 
    } 
}; 
struct Derived2:Derived { 
    virtual void foo(int x=0) override { 
    std::cout << "Derived2::foo()\n"; 
    Derived::foo(x); 
    } 
}; 

這裏我們打算每個foo調用其父foo。但由於Derived::foo不覆蓋與Base::foo相同的簽名,因此不會調用它。

添加overridefoo()Derived之後,我們得到編譯時錯誤。

是的,我實現了純虛函數Base::foo