当前位置: 首页 > news >正文

override 关键字的作用

override 关键字的作用

1. override 是什么?

override 是 C++11 引入的关键字,用于显式声明一个函数是基类中的虚函数(virtual)的重写
它用于 派生类(子类),确认该函数是对 基类(父类)方法的覆盖,增强了代码的可读性和安全性。


2. 为什么要使用 override

在 C++ 继承(Inheritance)机制中,派生类(子类)可以 重写(Override) 基类的 虚函数(Virtual Function)
但如果函数签名(返回值、参数列表)不匹配,可能导致隐藏(Hiding)错误,而不是正确的覆盖

📌 使用 override 的两个好处

  1. 编译器检查
    • 确保重写的是基类中的 虚函数,避免拼写错误或函数签名不匹配的问题。
  2. 提高可读性
    • 明确告诉读者 这个函数是重写基类方法,不是定义一个新方法

3. override 的使用方式

正确的用法
class Base {
public:
    virtual void show() {   // 基类中的虚函数
        std::cout << "Base class show()" << std::endl;
    }
};

class Derived : public Base {
public:
    void show() override {   // 正确:显式重写基类的虚函数
        std::cout << "Derived class show()" << std::endl;
    }
};

🔹 如果 Base 中的 show() 不是 virtual,那么 Derived 只是隐藏了它,而不是重写。
🔹 使用 override 让代码更加清晰,避免隐式的函数覆盖问题。


4. override 发现隐藏错误

错误示例(未正确覆盖基类方法)
class Base {
public:
    virtual void show(int x) {  // 虚函数带参数
        std::cout << "Base class show(int)" << std::endl;
    }
};

class Derived : public Base {
public:
    void show() override {  // ❌ 错误:基类没有 show(),只有 show(int)
        std::cout << "Derived class show()" << std::endl;
    }
};

🔸 🔴 编译会报错

error: 'show' marked 'override' but does not override any member functions

正确做法:

class Derived : public Base {
public:
    void show(int x) override {  // ✅ 正确匹配基类的 `show(int)`
        std::cout << "Derived class show(int)" << std::endl;
    }
};

🚀 因为 override 关键字强制要求基类中必须存在同样的方法接口,避免了隐藏错误!


5. override 结合 final 使用

如果不希望派生类继续重写该函数,可以使用 final 关键字:

class Base {
public:
    virtual void show() final {  // `final` 表示不能再被子类重写
        std::cout << "Base class show()" << std::endl;
    }
};

class Derived : public Base {
public:
    void show() override {  // ❌ 编译错误:不能重写 final 方法
        std::cout << "Derived class show()" << std::endl;
    }
};

🔴 编译错误

error: virtual function ‘virtual void Derived::show()’ overriding final function

6. override 在 ROS2 和 rclcpp_lifecycle 中的作用

ROS2 控制器 rclcpp_lifecycle::LifecycleNodeInterface 里,我们通常需要重写 LifecycleNode 的生命周期回调函数。例如:

#include <rclcpp/rclcpp.hpp>
#include <rclcpp_lifecycle/lifecycle_node.hpp>

class MyLifecycleNode : public rclcpp_lifecycle::LifecycleNode {
public:
    explicit MyLifecycleNode(const std::string & node_name)
        : LifecycleNode(node_name) {}

    // `on_configure()` - 进入 Inactive 状态时执行
    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn 
    on_configure(const rclcpp_lifecycle::State &) override {  
        RCLCPP_INFO(get_logger(), "节点已配置");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    // `on_activate()` - 进入 Active 状态时执行
    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn 
    on_activate(const rclcpp_lifecycle::State &) override {  
        RCLCPP_INFO(get_logger(), "节点已激活");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    // `on_deactivate()` - 进入 Inactive 状态时执行
    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn 
    on_deactivate(const rclcpp_lifecycle::State &) override {  
        RCLCPP_INFO(get_logger(), "节点已停用");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }
};

👉 在 ROS2 中,为了确保 LifecycleNode 正确覆盖基类的方法,必须使用 override
如果函数签名有误,比如 on_activate(int arg),编译器会报错,确保不会出现隐藏错误。


7. 总结

override 用于 显式声明派生类中的函数是基类虚函数的重写
好处:

  • 防止拼写错误
  • 避免隐藏错误
  • 提高可读性
    ✅ 在 C++ 继承(OOP)ROS2 LifecycleNode 生命周期管理 中经常使用。
    ✅ 结合 final 可以防止继续被派生类重写。

🚀 override 是 C++ 现代开发的重要特性,建议在所有重写 virtual 方法时都使用! 🚀

相关文章:

  • nodejs 037: Js Worker线程消息传递 Worker.postMessage() Worker.postMessage()
  • Unity Dots理论学习-4.ECS有关的模块(3)
  • 厘米和磅的转换关系
  • AI-Engine-Direct-Helper 快速上手及环境配置
  • FPGA简介|结构、组成和应用
  • C++、Dijkstra实现导航系统设计——课设
  • JavaScript 发起网络请求
  • AN 433:源同步接口的约束与分析
  • 【前端】自己从头实现一个gpt聊天页面
  • AI向量数据库之LanceDB快速介绍
  • 数据仓库与数据挖掘记录 三
  • stm32小白成长为高手的学习步骤和方法
  • 在C++的DLL文件中定义的结构体,在DLL外可以使用吗,如何使用?
  • 【3分钟极速部署】在本地快速部署deepseek
  • 基于 FPGA 的嵌入式系统硬件逻辑优化技术探究
  • Android 原生层SurfaceView截屏
  • 力扣刷题(数组篇)
  • DeepSeek本地部署详细指南
  • docker 逃逸突破边界
  • docker 部署nginx,nginx 504
  • 观察|本轮印巴冲突或促使印度空军寻求更先进战机
  • 美国4月CPI同比上涨2.3%低于预期,为2021年2月来最小涨幅
  • 法治课|争议中的“行人安全距离”于法无据,考量“注意义务”才更合理
  • 人民日报访巴西总统卢拉:“巴中关系正处于历史最好时期”
  • 张笑宇:物质极大丰富之后,我们该怎么办?
  • 【社论】人工智能将为教育带来什么