显式重载虚函数(C++11特性)


GCC4.7.0已经支持C++11标准的大部分功能了,今天尝试了下C++11的显式重载虚函数机制,感觉还是非常灵活的,语法结构如下:

  1. #include <iostream>   
  2.   
  3.   
  4. class A  
  5. {  
  6.     public:  
  7.         virtual void fun1()  
  8.         {  
  9.             std::cout << "A:1" << std::endl;  
  10.         };  
  11.         virtual void fun2()final  
  12.         {  
  13.             std::cout << "A:2" << std::endl;  
  14.         }  
  15.         virtual void fun3()  
  16.         {  
  17.             std::cout << "A:3" << std::endl;  
  18.         }  
  19.         void fun4()  
  20.         {  
  21.             std::cout << "A:4" << std::endl;  
  22.         }  
  23.         virtual void fun5()  
  24.         {  
  25.             std::cout << "A:5" << std::endl;  
  26.         }  
  27. };  
  28.   
  29.   
  30. class B final: public A  
  31. {  
  32.     public:  
  33.         virtual void fun1()override//(1)   
  34.         {  
  35.             std::cout << "B:1" << std::endl;  
  36.         }  
  37.         /*virtual void fun2()override//(2) 
  38.         { 
  39.             std::cout << "B:2" << std::endl; 
  40.         }*/  
  41.         /*virtual void fun2()(3) 
  42.         { 
  43.             std::cout << "B:2" << std::endl; 
  44.         }*/  
  45.         /*void fun2()(4) 
  46.         { 
  47.             std::cout << "B:2" << std::endl; 
  48.         }*/  
  49.         virtual void fun3()//(5)   
  50.         {  
  51.             std::cout << "B:3" << std::endl;  
  52.         }  
  53.         /*virtual void fun4()override//(6) 
  54.         { 
  55.             std::cout << "B:4" << std::endl; 
  56.         }*/  
  57.         virtual void fun4()//(7)   
  58.         {  
  59.             std::cout << "B:4" << std::endl;  
  60.         }  
  61.         void fun5()override//(8)   
  62.         {  
  63.             std::cout << "B:5" << std::endl;  
  64.         }  
  65. };  
  66.   
  67.   
  68. int main()  
  69. {  
  70.     std::cout << "A" << std::endl;  
  71.     A a;  
  72.     a.fun1();  
  73.     a.fun2();  
  74.     a.fun3();  
  75.     a.fun4();  
  76.     a.fun5();  
  77.   
  78.   
  79.     std::cout << "B" << std::endl;  
  80.     B b;  
  81.     b.fun1();  
  82.     b.fun2();  
  83.     b.fun3();  
  84.     b.fun4();  
  85.     b.fun5();  
  86.   
  87.   
  88.     std::cout << "A*" << std::endl;  
  89.     A* p = new B();  
  90.     p->fun1();  
  91.     p->fun2();  
  92.     p->fun3();  
  93.     p->fun4();  
  94.     p->fun5();  
  95. }  
以上是我自己编写的一个分析例子,下面对各部分进行一下分析:

(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)一旦一个的类的成员函数被声明为虚函数,那么就要么被重载要么被禁止重载,永远无法覆盖。

相关内容