• final/override控制


    先来复习下C++虚函数的特性:①重载函数需要与父类中虚函数的签名相同;②子类中的重载函数是否有virtual标识不影响继承树。按照这些特性,有如下代码

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class MethObject {
     5 
     6 public:
     7   virtual double Arith()=0;
     8   virtual void Print()=0;
     9 };
    10 
    11 class Printable:public MethObject {
    12 
    13 public:
    14   double Arith()=0;
    15   void Print(){
    16     cout << "Output is: " << Arith() << endl;
    17   }
    18 };
    19 
    20 class Add2:public Printable {
    21 
    22 public:
    23   Add2(double a,  double b):x(a), y(b) {}
    24   double Arith() {return x+y;}
    25 
    26 private:
    27   double x, y;
    28 };
    29 
    30 class Mul3:public Printable {
    31 
    32 public:
    33   Mul3(double a,  double b, double c):x(a), y(b), z(c) {}
    34   double Arith() {return x*y*z;}
    35 
    36 private:
    37   double x, y, z;
    38 };

    现在我们为了保持统一的打印风格,从而禁止Printable的子类重载Print虚函数,这就要用到C++11中的final关键字,做过Java的都知道finally关键字,他们的特性类似。

    稍微修改下代码,就可以看到编译错误:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class MethObject {
     5 
     6 public:
     7   virtual double Arith()=0;
     8   virtual void Print()=0;
     9 };
    10 
    11 class Printable:public MethObject {
    12 
    13 public:
    14   double Arith()=0;
    15   void Print() final{
    16     cout << "Output is: " << Arith() << endl;
    17   }
    18 };
    19 
    20 class Add2:public Printable {
    21 
    22 public:
    23   Add2(double a,  double b):x(a), y(b) {}
    24   double Arith() {return x+y;}
    25   void Print() {
    26       cout << "This is disallowed!" << endl;
    27   }
    28 
    29 private:
    30   double x, y;
    31 };
    32 
    33 class Mul3:public Printable {
    34 
    35 public:
    36   Mul3(double a,  double b, double c):x(a), y(b), z(c) {}
    37   double Arith() {return x*y*z;}
    38 
    39 private:
    40   double x, y, z;
    41 };

    编译结果如下:

    从编译器提示的信息,就可以很清楚的看到错误内容。

    C++虚函数的第二个特性,会导致一个“跨层”的问题,看如下代码:

     1 class A {
     2     virtual void Test() = 0;
     3 };
     4 
     5 class B:public A {
     6 };
     7 
     8 class C:public B {
     9     void Test(){}
    10 };

    类C中的Test函数仍然是虚函数,但是类C的继承者却不一定知道Test函数是否可以重载,或者还有一种情况,类C的继承者原意是想重载Test函数,但是手抖了下,写成了test(),在编译器看来这是OK的,会产生Test()与test()两个函数,但是在实际运用中,就会出现一些不必要的错误。为了解决这个问题,就需要用到override关键字(类似Java的修饰符中的@override)

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class A {
     5     virtual void Test() = 0;
     6     void test();
     7 };
     8 
     9 class B:public A {
    10 };
    11 
    12 class C:public B {
    13     void Test() override {}
    14     void test() override {}
    15 };

    编译结果如下:

    提示信息很清晰,一眼就能看懂,就不做过多解释了。

  • 相关阅读:
    Yii2 在模块modules间跳转时,url自动加模块名
    PHP 变量的间接引用(将某一字符串转化为变量)
    windows鼠标悬停任务栏 延迟时间 修改
    dede 常用标签和调用方法汇总
    dedecms ---m站功能基础详解
    apache 2.2 和2.4 目录权限访问设置的区别
    apache httpd.conf 配置局域网访问
    ajax php 点击加载更多
    dede调用当前栏目名 、dede sql
    dede 添加 栏目缩略图
  • 原文地址:https://www.cnblogs.com/lniwn/p/3403707.html
Copyright © 2020-2023  润新知