GCC4.7.0已經支持C++11標准的大部分功能了,今天嘗試了下C++11的顯式重載虛函數機制,感覺還是非常靈活的,語法結構如下:
- #include <iostream>
-
-
- class A
- {
- public:
- virtual void fun1()
- {
- std::cout << "A:1" << std::endl;
- };
- virtual void fun2()final
- {
- std::cout << "A:2" << std::endl;
- }
- virtual void fun3()
- {
- std::cout << "A:3" << std::endl;
- }
- void fun4()
- {
- std::cout << "A:4" << std::endl;
- }
- virtual void fun5()
- {
- std::cout << "A:5" << std::endl;
- }
- };
-
-
- class B final: public A
- {
- public:
- virtual void fun1()override//(1)
- {
- std::cout << "B:1" << std::endl;
- }
- /*virtual void fun2()override//(2)
- {
- std::cout << "B:2" << std::endl;
- }*/
- /*virtual void fun2()(3)
- {
- std::cout << "B:2" << std::endl;
- }*/
- /*void fun2()(4)
- {
- std::cout << "B:2" << std::endl;
- }*/
- virtual void fun3()//(5)
- {
- std::cout << "B:3" << std::endl;
- }
- /*virtual void fun4()override//(6)
- {
- std::cout << "B:4" << std::endl;
- }*/
- virtual void fun4()//(7)
- {
- std::cout << "B:4" << std::endl;
- }
- void fun5()override//(8)
- {
- std::cout << "B:5" << std::endl;
- }
- };
-
-
- int main()
- {
- std::cout << "A" << std::endl;
- A a;
- a.fun1();
- a.fun2();
- a.fun3();
- a.fun4();
- a.fun5();
-
-
- std::cout << "B" << std::endl;
- B b;
- b.fun1();
- b.fun2();
- b.fun3();
- b.fun4();
- b.fun5();
-
-
- std::cout << "A*" << std::endl;
- A* p = new B();
- p->fun1();
- p->fun2();
- p->fun3();
- p->fun4();
- p->fun5();
- }
以上是我自己編寫的一個分析例子,下面對各部分進行一下分析:
(1)顯式重載基類虛函數fun1
(2)顯式重載final的基類虛函數,編譯錯誤。final語法禁止派生類重載該虛函數。
(3)隱式重載基類final虛函數,編譯錯誤。
(4)不聲明virtual並隱式重載基類final虛函數,編譯錯誤。
(5)隱式重載基類虛函數,跟(1)比較有個缺陷:如果基類中不存在這個虛函數在編譯期無法檢測到錯誤
(6)顯式重載基類的普通成員函數,override只能重載虛函數,故編譯錯誤。
(7)重新聲明fun4函數為虛函數,覆蓋基類的fun4而不是重載。
(8)顯式重載基類虛函數fun5而不許要明確聲明virtual。
綜上所述:
(1)在派生類中重載基類虛函數應該顯式使用override,避免重載基類中不存在的虛函數,會在編譯期檢查到錯誤。
(2)如果想終止基類中的虛函數方法,而在B的類中不被重載需要明確的添加final修飾。
(3)一旦一個的類的成員函數被聲明為虛函數,那麼就要麼被重載要麼被禁止重載,永遠無法覆蓋。