final: final修飾符可用於修飾類,放在類名後面,被final修飾符修飾的類不能被繼承。示例代碼: final修飾符還可用於修飾類中的成員函數,但是成員函數必須是虛函數,被final修飾符修飾的虛函數在子類中不可以被重寫。示例代碼如下: override: 在C++11之前,在父類中用vir ...
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; } };