final说明符

  • 指定某给虚函数不能在派生类中被覆盖
    当在虚函数声明或定义中使用时,final 说明符确保函数为虚并指定其不可被派生类覆盖,否则程序为谬构(生成编译时错误)。

  • 某个类不能被派生
    当在类定义中使用时,final 指定此类不可在另一类的定义中的 基类说明符列表 中出现(换言之,不能派生于它),否则程序非良构(生成编译时错误)。

class Base
{
public:
    virtual void foo();
};
class A : public Base
{
public:
    void foo() final;
    void bar() final;
};
class B final : public A 
{
public:
    void foo() override; 
};
class C : public B 
{
};

运行结果如下:

void bar() final; // 错误: bar 非虚,因此它不能是 final 的
error: virtual function ‘virtual void B::foo()’ overriding final function
   25 |     void foo() override; // 错误:foo 不能被覆盖,因为它在 A 中是 final 的
main.cpp:19:10: note: overridden function is ‘virtual void A::foo()19 |     void foo() final; // Base::foo 被覆盖而 A::foo 是最终覆盖函数
main.cpp:28:7: error: cannot derive from ‘final’ base ‘B’ in derived type ‘C’
   28 | class C : B // 错误:B 是 final 的

当我们声明/定义了一个虚函数时候,派生类可以选择覆盖这个虚函数,也可以选择不覆盖。

  • 纯虚函数
    就是一旦某个基类声明了某个纯虚函数,它的派生类在实例化的时候就必须覆盖这个函数。

    class Base
    {
    public:
        virtual void foo() = 0;
    };
    void Base::foo ()
    {
        cout << "Base:foo" << endl;
    }
    class A : public Base
    {
    public: 
        /*void foo ()
        {
            cout << "A:foo" << endl;
        }*/
    };
    int main()
    {
        A objectA;
        objectA.foo();
        return 0;
    }
    

    本例中注释掉了A::foo()方法,所以在就会发生编译错误。

    main.cpp:26:7: error: cannot declare variable ‘objectA’ to be of abstract type ‘A’
       26 |     A objectA;
          |       ^~~~~~~
    main.cpp:15:7: note:   because the following virtual functions are pure within ‘A’:
       15 | class A : public Base
          |       ^
    main.cpp:10:6: note:virtual void Base::foo()10 | void Base::foo ()
          |      ^~~~
    
  • 一般说来,有要求的覆盖的方法,就应该有禁止覆盖的手段。

    class Base
    {
    public:
        virtual void foo() final;
    };
    void Base::foo ()
    {
        cout << "Base:foo" << endl;
    }
    class A : public Base
    {
    public: 
        void foo ()
        {
            cout << "A:foo" << endl;
        }
    };
    int main()
    {
        A objectA;
        objectA.foo();
        return 0;
    }
    

    运行结果如下:
    代码基本没变,只是Base::foo()声明的后面换成了final说明符。这时如果定义了A::foo()方法,就会产生如图的编译错误。

    17 |     void foo ()
    main.cpp:9:6: note: overridden function is ‘virtual void Base::foo()9 | void Base::foo ()
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值