news 2026/4/20 0:24:01

《你真的了解C++吗》No.025:隐藏(Hiding)而非覆盖(Overriding)的陷阱

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《你真的了解C++吗》No.025:隐藏(Hiding)而非覆盖(Overriding)的陷阱

《你真的了解C++吗》No.025:隐藏(Hiding)而非覆盖(Overriding)的陷阱

在解决了菱形继承的物理布局后,我们要面对一个非常隐蔽的逻辑陷阱。很多开发者在写派生类时,本想增强基类的功能,结果却不小心“抹杀”了基类的所有同名函数。

导言:消失的函数

在 C++ 中,我们习惯了重载(Overloading)——在同一个作用域里,函数名相同但参数不同。但在继承体系中,规则发生了剧变。

核心准则:派生类的作用域嵌套在基类的作用域之内。一旦派生类定义了与基类同名的函数,基类的所有同名函数在派生类中都会被立即“隐藏”。


一、 案例拆解:你以为的重载,其实是抹杀

看看这段极具迷惑性的代码:

classBase{public:voidfunc(){std::cout<<"Base::func()\n";}voidfunc(intx){std::cout<<"Base::func(int)\n";}};classDerived:publicBase{public:// 我只想增加一个带 double 参数的版本voidfunc(doubled){std::cout<<"Derived::func(double)\n";}};

当你调用时:

Derived d;d.func(3.14);// 成功,调用 Derived::func(double)d.func(10);// 警告!调用的是 Derived::func(double),10 被隐式转成了 doubled.func();// 编译报错!编译器说 Derived 类里找不到无参的 func()

为什么报错?
编译器在Derived的作用域里找到了func(double),于是它就此打住,不再去Base的作用域里寻找其他func的重载版本。这就是所谓的名字隐藏(Name Hiding)


二、 隐藏(Hiding)vs 覆盖(Overriding)

这是两个极易混淆的概念,它们的物理本质完全不同:

特性覆盖 (Overriding)隐藏 (Hiding)
前提基类函数必须是virtual只要函数名相同就会发生
签名函数签名(参数、返回值)必须完全一致函数名相同即可,参数可以不同
多态运行时的动态绑定编译时的作用域屏蔽
结果通过基类指针能调用到子类实现基类函数在子类中“不可见”

三、 如何找回被隐藏的函数?

如果你确实想在派生类中保留基类的那些重载版本,而不必手动一个个去重写一遍,C++ 提供了一个优雅的武器:using声明。

classDerived:publicBase{public:usingBase::func;// 声明:请把 Base 里的所有名为 func 的函数搬到我的作用域里来voidfunc(doubled){...}};// 现在 Derived 同时拥有了 func(), func(int), func(double)

四、 为什么 C++ 要这样设计?

这看起来像是个设计缺陷,但实际上是为了防止**“远距离干扰”**。
如果基类位于一个遥远的库中,某天库更新增加了一个新的重载版本,而你刚好在派生类里有一个类似名称的函数。如果没有隐藏规则,基类的新函数可能会在不经意间改变你代码的重载解析结果,导致难以排查的 Bug。

隐藏规则强制你:如果你要改,你就得明确知道你在改什么。


总结:作用域的权力

  • 名字查找(Lookup)优先于类型检查。只要名字对上了,编译器就不再往上找了。
  • 在继承体系中,如果你需要重载基类的函数,请务必配合使用using声明。
  • 记住:只有virtual配合相同的签名才是覆盖,其他的统统是隐藏

下一篇预告:聊完了编译器的静态查找,我们要看看运行时最昂贵的操作之一。当你不得不问一个基类指针“你到底是不是某个子类”时,幕后发生了什么?

➡️《你真的了解C++吗》No.026:运行时类型识别(RTTI)的开销——dynamic_cast 的代价。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 20:44:02

完成比完美更重要:敏捷热管理方法

&#x1f393;作者简介&#xff1a;科技自媒体优质创作者 &#x1f310;个人主页&#xff1a;莱歌数字-CSDN博客 &#x1f48c;公众号&#xff1a;莱歌数字&#xff08;B站同名&#xff09; &#x1f4f1;个人微信&#xff1a;yanshanYH 211、985硕士&#xff0c;从业16年 从…

作者头像 李华
网站建设 2026/4/19 11:23:19

强烈安利本科生必用的8款AI论文软件测评

强烈安利本科生必用的8款AI论文软件测评 2026年本科生AI论文工具测评&#xff1a;为什么你需要这份榜单&#xff1f; 随着人工智能技术的不断进步&#xff0c;越来越多的学术工具开始融入AI能力&#xff0c;帮助学生提升写作效率、优化内容质量。然而&#xff0c;面对市场上琳琅…

作者头像 李华
网站建设 2026/4/17 15:56:51

2026必备!10个AI论文软件,助研究生轻松搞定论文写作!

2026必备&#xff01;10个AI论文软件&#xff0c;助研究生轻松搞定论文写作&#xff01; AI 工具革新论文写作&#xff0c;研究生迎来高效新纪元 在学术研究日益精细化的今天&#xff0c;研究生们正面临前所未有的挑战。从选题构思到论文撰写&#xff0c;再到查重降重&#xff…

作者头像 李华
网站建设 2026/4/18 1:40:57

【tensorRT从零起步高性能部署】18-TensorRT基础-核心流程全面剖析

TensorRT的核心流程进行极致详细、全面的剖析&#xff0c;清晰呈现每个流程环节的核心组件、操作、输入输出及注意事项——这能帮助你从“步骤细节”双维度掌握TensorRT的完整工作逻辑。 TensorRT的核心流程本质是**“将通用深度学习模型&#xff08;ONNX/PyTorch/TensorFlow&…

作者头像 李华
网站建设 2026/4/18 10:47:33

什么是微模块机房?一文看懂其核心组成

在数据中心向“绿色化、智能化、边缘化”演进的今天&#xff0c;微模块机房&#xff08;Micro Module Data Center&#xff09; 已成为中小型数据中心和边缘计算场景的主流基础设施形态。与传统“现场砌墙分散部署”的建设模式不同&#xff0c;微模块机房采用标准化、预制化、集…

作者头像 李华