final:
final修飾符可用於修飾類,放在類名後面,被final修飾符修飾的類不能被繼承。示例程式碼:
// 正確的示範 #include <iostream> class A { public: void show_a_info() { std::cout << "i am class A" << std::endl; } }; class B : public A { public: void show_b_info() { std::cout << "i am class B" << std::endl; } }; int main() { B b; b.show_a_info(); b.show_b_info(); return 0; } // 輸出: // i am class A // i am class B
// 錯誤的示範 #include <iostream> class A final { public: void show_a_info() { std::cout << "i am class A" << std::endl; } }; class B : public A { public: void show_b_info() { std::cout << "i am class B" << std::endl; } }; int main() { B b; b.show_a_info(); b.show_b_info(); return 0; } // 編譯報錯:錯誤 2 error C3246: “B”: 無法從“A”繼承,因為它已被宣告為"final"
final修飾符還可用於修飾類中的成員函式,但是成員函式必須是虛擬函式,被final修飾符修飾的虛擬函式在子類中不可以被重寫。示例程式碼如下:
// 正確的示範 #include <iostream> class A { public: virtual void show_info() { std::cout << "i am class A" << std::endl; } virtual void test_final() final { return; } }; class B : public A { public: void show_info() // 可以被重寫 { std::cout << "i am class B" << std::endl; } void test_final() // 編譯報錯:A::test_final宣告為final的函式無法被B::test_final重寫 { int count = 0; // do_something() return; } }; int main() { A *a_ptr = new B(); a_ptr->show_info(); return 0; }
override:
在C++11之前,在父類中用virtual宣告一個虛擬函式,在子類中進行重寫時,可以省略virtual修飾符,但是子類中重寫的函式就算省略了virtual修飾符,它依然是個虛擬函式,當我們閱讀程式碼時,子類中的這個函式由於沒有virtual修飾符修飾,我們不去看父類的定義並不會知道在子類中這是一個虛擬函式,為了解決可讀性問題,我們可以在子類中也加上virtual修飾符,但也同樣會帶來如下程式碼中的問題:
class A { public: virtual void show_info(int x) { std::cout << "i am class A" << std::endl; } }; class B : public A { public: virtual void show_info(float x) { std::cout << "i am class B" << std::endl; } };
本意是想重寫父類中的show_info(int x)函式,但是寫成了show_info(float x),這樣寫就已經不是重寫了,而是變成了過載。為了解決可讀性及這種重寫被不小心寫成過載的問題,在C++11中當我們想重寫父類的虛擬函式時,可以在子類中重寫的虛擬函式後面加上override修飾符,這樣既標識在子類中這是在重寫父類中的虛擬函式,同時也可以防止重寫被誤寫為過載,因為當子類中對應的函式宣告和父類中不一致時,是編譯不過的,示例如下:
// 正確的示範 #include <iostream> class A { public: virtual void show_info(int x) { std::cout << "i am class A" << std::endl; } }; class B : public A { public: //virtual void show_info(float a) override // 錯誤error C3668: “B::show_info”: 包含重寫說明符“override”的方法沒有重寫任何基類方法 //{ // std::cout << "i am class B" << std::endl; //} virtual void show_info(int a) override // 正確 { std::cout << "i am class B" << std::endl; } };