news 2026/5/30 20:00:59

转向现代C++——在意为改写的函数添加 override

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
转向现代C++——在意为改写的函数添加 override

文章目录

    • 在意为改写的函数添加 override
      • 未添加 `override`
      • 显式添加 `override`
      • 引用限定符

在意为改写的函数添加 override

虚函数改写(Overriding)是实现多态的核心,但它的隐式匹配规则非常严苛。如果开发者稍有疏忽,本意是“改写(Override)”的函数就会变成“重载(Overload)”或“隐藏(Hide)”,而编译器对此往往保持沉默。

虚函数改写的严格条件

在 C++ 中,派生类函数要想真正改写基类的虚函数,必须满足以下所有条件:

  1. 函数名相同
  2. 形参类型完全相同
  3. 常量性(const属性)完全相同
  4. 返回值类型和异常规格(Exception specification)必须兼容
  5. (C++11 新增)引用限定符(Reference qualifiers)完全相同

未添加override

classBase{public:virtualvoiddoWork();// 基础虚函数virtualvoidprocess(intx);// 带参数virtualvoiddisplay()const;// const 函数};classDerived:publicBase{public:// 错误 1:漏掉了 const,变成了一个全新的虚函数,隐藏了 Base::doWorkvirtualvoiddoWork();// 错误 2:参数类型写错(int 变成了 unsigned int),变成了重载(Overload)virtualvoidprocess(unsignedintx);// 错误 3:函数名大小写写错,变成了完全无关的新函数virtualvoidDisPlay()const;};

:::color4

  • 编译期无警告****:上述Derived中的三个函数,在 C++98/C++11 语法下完全合法。编译器会认为你是故意在派生类里增加新函数的。
  • 运行时行为诡异(多态失效)

:::

Base*bp=newDerived();bp->process(10);// 期望调用 Derived::process,但实际上调用了 Base::process!

显式添加override

通过在派生类函数后面加上override关键字,向编译器明确传达了意图:“我这个函数绝对是改写基类的,请帮我检查!

classDerivedCorrected:publicBase{public:// 编译期报错!Base 中没有非 const 的 doWork()voiddoWork()override;// 编译期报错!Base 中没有接收 unsigned int 的 processvoidprocess(unsignedintx)override;// 编译期报错!Base 中没有名为 DisPlay 的函数voidDisPlay()constoverride;// ---------------- 正确的改写 ----------------voiddisplay()constoverride;// 完美匹配!编译通过};
为什么强制使用 override?
  1. 让编译器做打字工只要有任何一处不匹配(比如漏了const,改了参数类型),编译器会立刻拒绝编译,并给出精准的错误提示。
  2. 无成本的代码文档任何阅读代码的人一眼就能看出哪些函数是多态的关键节点,无需频繁跳回基类去确认。
  3. 安全重构基类如果哪天你需要修改基类Base::doWork()的签名(比如加个参数),所有未同步修改的派生类都会在编译期报警,而不会在运行时悄悄崩溃。

引用限定符

C++11 允许根据对象是左值还是右值来调用不同的成员函数。如果基类指定了引用限定符,派生类改写时也必须完全一致,否则也会变成全新的函数

classWidget{public:// 只有左值对象 (*this 是左值) 才能调用此函数virtualvoiddata()&;// 只有右值对象 (*this 是右值) 才能调用此函数virtualvoiddata()&&;};classSubWidget:publicWidget{public:// 如果不加 override,这只是一个没有引用限定的新函数,会隐藏 Widget::data// 加上 override 后,编译器会立刻发现你漏掉了 & 或 && 从而报错voiddata()override;// 错误:无法通过编译voiddata()&override;// 正确:成功改写左值版本};
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 19:57:38

3步掌握Unity游戏马赛克移除:UniversalUnityDemosaics完整指南

3步掌握Unity游戏马赛克移除:UniversalUnityDemosaics完整指南 【免费下载链接】UniversalUnityDemosaics A collection of universal demosaic BepInEx plugins for games made in Unity3D engine 项目地址: https://gitcode.com/gh_mirrors/un/UniversalUnityDe…

作者头像 李华
网站建设 2026/5/30 19:57:30

基于ESP8266与ADS1115的智能灌溉压力监测系统DIY指南

1. 项目概述:从灌溉故障到智能预警的DIY之路去年夏天,我给自家花园装了一套自动灌溉系统,并接入了Home-Assistant,想着从此就能高枕无忧,做个“甩手掌柜”。没想到,现实很快给了我几个下马威。系统总在凌晨…

作者头像 李华
网站建设 2026/5/30 19:54:31

设备树驱动修改

根据您提供的原始设备树、修改后设备树、修改前的GPIO状态和修改后的GPIO状态,我通过对比分析,总结出以下引脚配置的变化。这些变化反映了您基于BCU原理图对设备树进行的调整。一、设备树修改概览主要修改集中在以下几个部分:新增/启用了 CAN…

作者头像 李华
网站建设 2026/5/30 19:52:48

百度网盘提取码3秒获取:一键解锁加密资源的终极指南

百度网盘提取码3秒获取:一键解锁加密资源的终极指南 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 还在为百度网盘加密资源而烦恼吗?每次遇到需要提取码的分享链接,都要花费大量时间在各种…

作者头像 李华