跳至主要內容

抽象基类与纯虚方法

LincZero大约 3 分钟

抽象基类与纯虚方法

抽象基类

抽象基类

  • 简概

    • 这是一种理念。具系统性,更规范

      (一种学院派思想认为,如果涉及基础层次,则只能将那些不会被用作基类的类设计为具体类)

  • 好处

    • 可以将ABC看作是一种必须实施的接口,要求派生类覆盖其纯虚函数,迫使派生类遵循ABC设计的接口规则

      (因为纯虚函数没有定义,如果派生类没有覆盖其纯虚函数,则会报错)

    • 使用ABC使得组件设计人员能够制定“接口约定”

  • 特点

    • 抽象基类(abstract base class,ABC)

      抽象基类的命名可以以ABC作为结尾标注

    • 抽象基类不能创建对象

      与之相反的,其派生类可为具体类(concrete class),这表示可以创建这些类型的对象

  • 使用场景

    • 比如圆和椭圆可以继承一个抽象基类,而不是让圆去继承椭圆
    • 抽象基类为原和椭圆共性的抽象

纯虚函数

  • 简概

    • 纯虚函数(pure virtual function)提供未实现的函数
  • 使用

    • 定义方法:虚函数,且在函数原型声明的结尾处加=0
    • 例如:virtual double Area() const = 0;
  • 特点

    • 当类声明中包含纯虚函数时,指出类是一个抽象基类,即不能创建该类的对象

      这样设计的理念是:要称为真正的ABC,必须至少包含一个纯虚函数

    • 在类中可以不定义该纯虚函数(只用原型声明就行,定义让派生类去实现)

override(C++11)重写

  • 参考:https://www.cnblogs.com/xinxue/p/5471708.html
  • 使用
    • 在继承抽象基类的头文件处重写函数后面加上该关键字
    • 如:virtual QString name() override;
    • 用内联函数的方式重写时:virtual QString name() override {/**/};(override不是放在最后面)
  • 作用
    • 可以避免派生类中忘记重写虚函数的错误
    • C++11 中的 override 关键字,可以显式的在派生类中声明,哪些成员函数需要被重写,如果没被重写,则编译器会报错
    • 这样,即使不小心漏写了虚函数重写的某个苛刻条件,也可以通过编译器的报错,快速改正错误
    • 举例
      • 基类定义一个虚基类virtual fn1,派生类要重写他时可能会打错字virtual fn2, 这时如果没有override关键字他会认为你要重新定义一个新的虚基类而不是实现虚基类,不报错! 但要是加了override关键字他会发现你想覆盖的虚基类并不存在,就会给你报错!

小结

  1. 公有继承

纯虚函数 => 继承的是:接口 (interface)

普通虚函数 => 继承的是:接口 + 缺省实现 (default implementation)

非虚成员函数 =>继承的是:接口 + 强制实现 (mandatory implementation)

  1. 不要重新定义一个继承自基类的非虚函数( never redefine an inherited non-virtual function)

  2. 在声明需要重写的函数后,加关键字 override