【转】C++ 函数后加override和final

本文介绍了C++中虚函数的重写方法及override和final关键字的应用。使用override可以确保子类正确重写了父类的虚函数,而final则用于禁止进一步的重写或继承。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:https://www.cnblogs.com/whlook/p/6501918.html

1. override 重载

  当你在父类中使用了虚函数时候,你可能需要在某个子类中对这个虚函数进行重写,以下方法都可以:

复制代码

class A
{
    virtual void foo();
}
class B :public A
{
    void foo(); //OK
    virtual foo(); // OK
    void foo() override; //OK
}

复制代码

  如果不使用override,当你手一抖,将foo()写成了f00()会怎么样呢?结果是编译器并不会报错,因为它并不知道你的目的是重写虚函数,而是把它当成了新的函数。如果这个虚函数很重要的话,那就会对整个程序不利。

  所以,override的作用就出来了,它指定了子类的这个虚函数是重写的父类的,如果你名字不小心打错了的话,编译器是不会编译通过的:

复制代码

class A
{
    virtual void foo();
};
class B :A
{
    virtual void f00(); //OK
    virtual void f0o()override; //Error 
};

复制代码

  为了减少程序的运行时错误,还是养成重写虚函数加上override的习惯吧。

2.final

  当不希望某个类被继承,或不希望某个虚函数被重写,可以在类名和虚函数后添加final关键字,添加final关键字后被继承或重写,编译器会报错。例子如下:

复制代码

class Base
{
    virtual void foo();
};
 
class A : Base
{
    void foo() final; // foo 被override并且是最后一个override,在其子类中不可以重写
    void bar() final; // Error: 父类中没有 bar虚函数可以被重写或final
};

class B final : A // 指明B是不可以被继承的
{
    void foo() override; // Error: 在A中已经被final了
};
 
class C : B // Error: B is final
{
};
C++ 中,函数声明后带有 `override` 关键字表示该函数是**对基类虚函数的重写(覆盖)**。这是 C++11 引入的特性,用于明确标识派生类对基类虚函数的实现,同时帮助编译器检查覆盖的正确性。以下是详细解释: --- ### **1. `override` 的作用** #### **(1) 明确标识重写** - 告诉编译器:当前函数必须重写基类的虚函数,否则编译报错。 - 提高代码可读性,明确表达设计意图。 #### **(2) 编译时检查** - 如果基类中没有同名的虚函数(或签名不匹配),编译器会报错,避免因拼写错误或参数列表不一致导致的意外行为。 --- ### **2. 使用示例** #### **(1) 正确使用 `override`** ```cpp class Base { public: virtual void foo(int x) { /* 基类实现 */ } }; class Derived : public Base { public: void foo(int x) override { // 正确重写基类的虚函数 /* 派生类实现 */ } }; ``` #### **(2) 错误使用场景(触发编译错误)** ```cpp class Base { public: virtual void bar(float x) { /* 基类实现 */ } }; class Derived : public Base { public: void bar(int x) override { // 错误:参数类型不匹配(float vs int) /* 编译报错:没有基类虚函数可被覆盖 */ } }; ``` --- ### **3. 与 `virtual` 的关系** - **基类**:虚函数需用 `virtual` 声明(如 `virtual void foo()`)。 - **派生类**: - 可省略 `virtual`,直接用 `override`(推荐)。 - 若同时使用 `virtual` `override`(如 `virtual void foo() override`),效果相同,但冗余。 ```cpp class Base { public: virtual void foo() {} }; class Derived : public Base { public: void foo() override { /* 正确 */ } // 推荐:仅用 override // virtual void foo() override { /* 冗余但合法 */ } }; ``` --- ### **4. 为什么推荐使用 `override`?** #### **(1) 避免隐式错误** - 若基类函数签名变更(如参数类型修改),派生类未同步修改时: - 无 `override`:静默成为新函数(非预期行为)。 - 有 `override`:编译报错,强制开发者处理。 #### **(2) 代码清晰性** - 明确表达“此函数必须覆盖基类虚函数”的意图。 --- ### **5. 对比其他关键字** | 关键字 | 作用 | |--------------|----------------------------------------------------------------------| | `virtual` | 声明基类函数为虚函数(支持多态)。 | | `override` | 显式标识派生类函数必须覆盖基类虚函数C++11 起)。 | | `final` | 禁止进一步覆盖该虚函数C++11 起)。 | ```cpp class Base { public: virtual void foo() {} }; class Derived : public Base { public: void foo() override final { // 允许同时使用 override final /* 可被覆盖,但派生类的派生类不能再覆盖 */ } }; ``` --- ### **6. 常见问题** #### **(1) 能否在非虚函数上使用 `override`?** - **不行**。`override` 必须用于覆盖基类的虚函数,否则编译报错。 #### **(2) 析构函数与 `override`** - 若基类析构函数是虚函数,派生类析构函数应使用 `override`: ```cpp class Base { public: virtual ~Base() {} }; class Derived : public Base { public: ~Derived() override {} // 正确:覆盖基类虚析构函数 }; ``` #### **(3) 多重继承中的 `override`** - 在多重继承中,`override` 需确保匹配某个基类的虚函数: ```cpp class Base1 { virtual void foo() {} }; class Base2 { virtual void foo() {} }; class Derived : public Base1, public Base2 { public: void foo() override { /* 同时覆盖 Base1 Base2 的 foo() */ } }; ``` --- ### **总结** - **`override` 是 C++11 的语法糖**,用于明确标识虚函数覆盖,增强代码安全性可读性。 - **必须与基类虚函数严格匹配**(名称、参数、返回值、const 限定符等)。 - **推荐始终使用**,避免因拼写错误或签名不一致导致的逻辑错误。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值