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

C++中的覆盖和隐藏详解

继承是面向对象编程的重要特性,在c++中,当父类与子类出现同名函数时,会出现两种情况:覆写和隐藏,本文主要讨论c++中这两种情况的特点和使用区别

2. 共性

当子类继承父类,并且子类中有父类同名函数,那么子类将隐藏父类中所有同名函数,不可以对父类中同名函数直接进行访问,此时子类调用父类中函数需要用域操作符::

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#include<iostream>

usingnamespacestd;

classA{

public:

voidfun1(){

cout<<"A::fun1()"<<endl;

}

voidfun1(int){

cout<<"A::fun1(int)"<<endl;

}

voidfun2(){

cout<<"A::fun2()"<<endl;

}

};

classB:publicA{

public:

voidfun1(){

cout<<"B::fun1()"<<endl;

}

};

intmain(){

B b;

b.fun1();//调用子类b的fun1()函数

//b.fun1(3);尝试调用父类fun1(int)函数会报错:error:no matching function for call to 'B::fun1(int)'

b.A::fun1();//调用父类A的fun1()函数

b.A::fun1(3);//调用父类A的fun1(int)函数

b.fun2();//调用父类A的fun2()函数

return0;

}

b调用fun1()函数,会调用子类b的fun1()函数,而尝试使用b.fun(3)调用父类的void fun(int)函数时,会报错,因为父类中的同名函数都被隐藏。此时调用父类中函数的方法是使用域操作符::。

当父类中同名函数拥有virtual修饰符修饰时,此时子类对父类函数进行覆写

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#include<iostream>

usingnamespacestd;

classA{

public:

virtualvoidfun1(){

cout<<"A::fun1()"<<endl;

}

voidfun1(int){

cout<<"A::fun1(int)"<<endl;

}

voidfun2(){

cout<<"A::fun2()"<<endl;

}

};

classB:publicA{

public:

virtualvoidfun1(){

cout<<"B::fun1()"<<endl;

}

};

intmain(){

B b;

b.fun1();//调用子类b的fun1()函数

//b.fun1(3);尝试调用父类fun1(int)函数会报错:error:no matching function for call to 'B::fun1(int)'

b.A::fun1();//调用父类A的fun1()函数

b.A::fun1(3);//调用父类A的fun1(int)函数

b.fun2();//调用父类A的fun2()函数

return0;

}

可见即使是虚函数覆写,也会隐藏父类中的所有同名函数。

当子类与父类有同名函数,无论是覆写还是隐藏的方式,在子类自身进行函数调用时,会调用子类函数而隐藏父类的所有同名函数,要访问父类函数需要通过域操作符进行访问。

3. 区别

覆写与隐藏的区别可以体现在基类指针的使用上,比如以下程序

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

#include<iostream>

usingnamespacestd;

classA{

public:

voidfunction1(){

cout<<"A::function1"<<endl;

}

virtualvoidfunction2(){

cout<<"A::function2"<<endl;

}

};

classB:publicA{

public:

//隐藏基类function1

voidfunction1(){

cout<<"B::function1"<<endl;

}

};

classC:publicA{

public:

//覆写基类function2

virtualvoidfunction2(){

cout<<"C::function2"<<endl;

}

};

intmain(){

A *a;

B b;

C c;

a=&b;

a->function1();

a=&c;

a->function2();

return0;

}

b隐藏基类的同名函数function1(),当基类指针a指向子类b时,调用的是a的function1()函数,而子类c覆写a的同名函数function2(),当基类a指针指向子类c,调用的是c的function2()函数。

利用覆写的特点,可以实现c++的多态特性。

4. 区分

隐藏:当父类函数与派生类函数同名,并且父类函数无virtual关键字修饰,无论父类与派生类参数个数与类型是否相同,此时派生类函数隐藏父类所有同名函数

覆写:当父类函数与派生类函数同名,并且参数相同,返回值相同,并且父类函数有virtual关键字修饰,此时派生类函数覆写父类函数

5.参考文章

C++继承中的重载,覆盖和隐藏

总结

本篇文章就到这里了,希望能够给你带来帮助


http://www.jsqmd.com/news/838714/

相关文章:

  • 【NotebookLM生成模型实战指南】:20年AI架构师亲授5大高效提示工程技巧,助你3天提升87%知识整合效率
  • 打破壁垒:APK安装器让Windows与Android应用无缝融合
  • Apex Legends终极压枪指南:智能武器检测与自动化脚本完全解析
  • PPTist在线演示工具:零基础打造专业级幻灯片的实战指南
  • Redis入门:5大数据类型全解析
  • Obsidian Jupyter插件终极指南:在笔记中直接运行Python代码的完整教程
  • 猫抓cat-catch浏览器扩展全攻略:三步掌握网页资源高效捕获技术
  • 【NotebookLM提示工程实战指南】:20年AI工程师亲授5大高转化提示模板与避坑清单
  • 基于Llama.cpp的本地AI智能体框架:从工具调用到多轮对话实践
  • 为什么APK安装器改变了Windows用户使用安卓应用的方式?
  • Gemini-Skill开源项目解析:轻量级AI技能包的设计与工程实践
  • 音频实战:边播边缓存、预加载与断点续播完整实现
  • 终极指南:FanControl风扇控制软件如何一键解决你的PC散热烦恼?
  • 京东自动化抢购工具:3步实现茅台等高热度商品秒杀
  • KANBoost:基于Kolmogorov-Arnold网络的内存预取优化技术
  • 2026年5月新版国内热式气体质量流量计生产厂家十大品牌 - 流量计品牌
  • 基于Node.js+Vue+SQLite的轻量级库存管理系统设计与实现
  • 杰发科技AC7840——CAN通信波形深度解析(7)_从隐性显性到帧结构
  • 用STM32F103驱动0.96寸OLED屏幕(SSD1306):从硬件接线到显示第一行‘Hello World‘的完整流程
  • 2026年西南奶油板市场大揭秘:哪家厂家成热门之选? - 博客万
  • Synology Photos人脸识别补丁:3步解锁x86设备AI照片管理能力
  • 从零开始掌握无人机仿真:XTDrone完整实战指南
  • HiveWE:魔兽争霸III地图编辑器的终极现代化解决方案
  • 如何在浏览器中快速解锁加密音乐文件:完整指南
  • 基于Helm Chart在K8s生产环境部署Dify.AI的完整指南
  • 厂房环保工程承包怎么选?合规资质、一体化施工是关键 - 品牌2025
  • 2026-05-18:统计凯撒加密对数目。用go语言,给定一个长度都为 m、只含小写字母的字符串数组 words(共 n 个)。如果可以通过对两个字符串 s、t 反复执行同一种“整体循环右移字母”的操
  • LightDB 数值格式化深度解析:从数据库内核到DBeaver显示的完整链路
  • Adobe-GenP完整指南:5步轻松激活Adobe全系列软件
  • 3步掌握BilibiliDown:跨平台B站视频下载神器轻松收藏你喜欢的视频