c++成员函数的重载、覆盖、隐藏区别
成员函数的重载、覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防。
重载与覆盖
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
 
以下示例中,函数 Base::f(int) 与 Base::f(float) 相互重载,而 Base::g(void) 被 Derived::g(void) 覆盖。
#include <iostream>using namespace std;class Base
{
public:void f(int x){ cout << "Base::f(int) " << x << endl; }void f(float x){ cout << "Base::f(float) " << x << endl; } virtual void g(void){ cout << "Base::g(void)" << endl;}
};class Derived : public Base
{
public:virtual void g(void){ cout << "Derived::g(void)" << endl;}
};int main(void)
{Derived d;Base *pb = &d;pb->f(42);     // Base::f(int) 42pb->f(3.14f);  // Base::f(float) 3.14pb->g();       // Derived::g(void)return 0;
}

令人迷惑的隐藏规则

本来仅仅区别重载与覆盖并不算困难,但是C++的隐藏规则使问题复杂性陡然增加。

这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual

关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual

关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

以下示例中:

(1)函数Derived::f(float) 覆盖了 Base::f(float)。

(2)函数Derived::g(int)   隐藏了 Base::g(float),而不是重载。

(3)函数Derived::h(float) 隐藏了 Base::h(float),而不是覆盖。

#include <iostream>using namespace std;class Base
{
public:virtual void f(float x){ cout << "Base::f(float) " << x << endl; }void g(float x){ cout << "Base::g(float) " << x << endl; }void h(float x){ cout << "Base::h(float) " << x << endl; }
};class Derived : public Base
{
public:virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }void g(int x){ cout << "Derived::g(int) " << x << endl; }void h(float x){ cout << "Derived::h(float) " << x << endl; }
};

“隐藏”的发生可谓神出鬼没,常常产生令人迷惑的结果。

如以下示例中,pb和 pd 指向同一地址,按理说运行结果应该是相同的,可事实并非这样。

int main(void)
{Derived d;Base *pb = &d;Derived *pd = &d;pb -> f(3.14f); // Derived::f(float) 3.14pd -> f(3.14f); // Derived::f(float) 3.14pb -> g(3.14f); // Base::g(float) 3.14pd- > g(3.14f); // Derived::g(int) 3 (surprise!)pb -> h(3.14f); // Base::h(float) 3.14 (surprise!)pd -> h(3.14f); // Derived::h(float) 3.14return 0;
}

摆脱隐藏

隐藏规则引起了不少麻烦。示例8-2-3 程序中,语句pd->f(10)的本意是想调用函数 Base::f(int),但是 Base::f(int) 不幸被 Derived::f(char *str) 隐藏了。由于数字10不能被隐式地转化为字符串,所以在编译时出错。

class Base
{
public:void f(int x);
};class Derived : public Base
{
public:void f(char *str);
};void Test(void)
{Derived *pd = new Derived;pd -> f(10);             // error
}

c++成员函数的重载、覆盖、隐藏区别相关推荐

  1. 深入理解成员函数的重载、隐藏、覆盖规则(二)

    本文作者:islwj 本文出处:http://blog.csdn.net/islwj 声明: 本文可以不经作者同意, 任意复制, 转载, 但任何对本文的引用都请保留文章开始前三行的作者, 出处以及声明 ...

  2. C++中类成员函数的重载、覆盖和隐藏的区别,超清楚!

    转载:https://www.cnblogs.com/liubo1/p/5925746.html 1.成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: ...

  3. C++成员函数的重载、覆盖与隐藏

    C++成员函数的重载.覆盖与隐藏 成员函数的重载.覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防. 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在 ...

  4. 成员函数的重载、覆盖与隐藏(详细)【转】

    (转自:https://blog.csdn.net/weixin_42205987/article/details/81569744) 成员函数的重载.覆盖与隐藏 成员函数的重载(overload). ...

  5. c++ 重载 覆盖 隐藏的区别和执行方式

    成员函数被重载的特征(1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual 关键字可有可无. 覆盖是指派生类函数覆盖基类函数,特征是 (1)不同的范围(分别位 ...

  6. 成员函数的重载,覆盖与隐藏

    重载 具有相同的作用域(即同一个类定义中) 函数名字相同 参数类型.顺序或数目不同(包括const参数和非const参数) virtual关键字可有可无 覆盖 是指派生类重新实现(或改写)了基类的成员 ...

  7. C++之常引用对象只能调用常成员函数、重载为成员函数和友元函数的区别

    近日写了一道题,遇到了新bug,使博主对C++的逻辑严密性有了更深的体会,特写此博客.本文标题是对两个bug的总结,即本文内容分为两部分. 题目如下: 设计一个CShape抽象类,类中包含纯虚函数   ...

  8. 问题:1.sizeof;2.重载覆盖隐藏;3.内存管理

    1-1.问:"char a[10]; int len = strlen(a);",len等于多少? 解析:strlen计算从数组a的第一个元素开始到'\0'总共有多少个字符(不包含 ...

  9. C++——运算符的重载---以成员函数方式重载---以友元函数方式重载

    一.运算符的重载 1.运算符的重载 允许把标准运算符(如+ - * /等运算符)应用于自定义数据类型的对象,可以提高程序的可读性,运算符的重载本质上还是函数重载.运算符仅仅是语法上的方便,它是另一种函 ...

最新文章

  1. Linux工具之curl与wget高级使用
  2. html字体阴影怎么设置6,css怎么设置字体阴影
  3. 嗨淘V12刷任务点赞系统源码手动派单版本
  4. Server Host Cannot be null解决方法
  5. 运维:使用awk命令获取文本的某一行,某一列
  6. 记一次反制追踪溯本求源
  7. JavaScript中this指针指向的彻底理解
  8. DEDECMS v5.7 实现导航条下拉二级菜单
  9. 移动端学习笔记(黑马教程)-仿京东首页
  10. 计算机word制作成绩单,如何用word批量制作学生成绩单?
  11. 【计算机基础恶补】南桥北桥
  12. 基于微信小程序的物流仓储系统
  13. C#与C++混合编程及性能分析
  14. 物联网云平台DTU Modbus协议 上位机 下位机 源码 源代码 程序
  15. 游戏服务器租用配置选择攻略(大型端游及中小型网页游戏选型)
  16. 华为云对象存储连接测试
  17. NSString NSArray NSDictionary NSSet 中的部分方法
  18. mac lion 系统安装
  19. VS2017 打包exe,msi文件
  20. 艾森豪威尔时间管理法则

热门文章

  1. Object.defineProperty()
  2. Java--对象与类(三)
  3. LightHouse/归并排序
  4. Protocol Buffers简明教程
  5. css中float用法
  6. 2022-2028年中国成人艺术培训行业市场前瞻与投资战略规划分析报告
  7. oracle手工启动,SQLSERVER服务手工启动 批处理文件
  8. Swift 中 insetBy(dx: CGFloat, dy: CGFloat) - CGRect 用法详解
  9. FFmpeg学习4:音频格式转换
  10. Spark源码分析之七:Task运行(一)