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

C++中重载(overload)、重写(override,也叫做“覆盖”)和重定义(redefine,也叫作“隐藏”)的区别?

在C++中,允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。

重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。

当调用一个重载函数或重载运算符时,编译器通过把使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。

重载对于C++编程来说,其重要意义不言而喻,然而面试官常问的不仅是重载,还会问到重写和重定义。这让许多面试者都会感到一头雾水。

所以今天我们就来聊聊重载、重写和重定义之间的区别。

一、概念梳理

(1)重载

重载分为两种类型,一种是函数重载,另一种是运算符重载。

一般指函数重载,即相同作用域中被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数(即多个函数具有相同的名字),但参数的数目和类型各不相同(其中数目和类型均相同,如果顺序不同也是可以的),然后根据参数列表确定调用哪个函数。
​ 特点: ​
①这里主要考虑的是面向对象,在面向对象中,重载只是在类的内部存在,即同一个类中。抛除面向对象的话,在同一个作用域中即可。
②函数名相同,参数列表不同 ​
③重载不关心函数返回类型,不能靠返回类型来判断。

class A
{public:void test(int i);void test(double i);			//overloadvoid test(int i, double j);		//overloadvoid test(double i, int j);		//overload
};

(2)重写(又叫“覆盖”)

指派生类中存在重新定义的基类函数。
特点:
①其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致,只有函数体不同(花括号内)。 ​
②派生类调用时会调用派生类的重写函数,不会调用被重写函数。
③重写的基类中被重写的函数必须有virtual修饰。

#include<iostream>
using namespace std;//基类
class Base
{
public:virtual void fun(int i){ cout << "Base::fun(int) : " << i << endl;}
};//派生类
class Derived : public Base
{
public:virtual void fun(int i){ cout << "Derived::fun(int) : " << i << endl;}
};int main()
{Base b;Base * pb = new Derived();pb->fun(3);				//Derived::fun(int)system("pause");return 0;}

(3)重定义(又叫“隐藏”)

指派生类的函数屏蔽了与其同名的基类函数。
特点:
①函数名称相同,但是返回值可以不同。
②作用域分别位于基类和派生类之中;
注意:
①如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无virtual,基类的函数被隐藏。
②如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有vitual关键字,此时,基类的函数被隐藏。
所以,此处只要求是同名函数,不管参数列表是否相同,基类函数都会被隐藏。

class A
{
public:void fun(){cout<<"A"<<endl;}virtual void fun1(int i,int j){cout << "A::fun() : " <<i<<" "<<j<<endl;}
};class B:public A
{
public://两个函数参数相同,但基类函数不是虚函数。void fun() //隐藏父类的 fun 函数{cout<<"B"<<endl;}//两个函数参数不同,无论基类函数是否是虚函数,基类函数都会被屏蔽。virtual void fun1(double i) //重写基类A中的fun1(){cout << "B::fun(): " << i << endl;}
}int main()
{B b;b.fun3(5);//b.fun3(1, 2);隐藏了基类的同名函数,所以不能运行return 0;
}

2.区别对比

(1)重载和重写的区别:

​①作用域的区别 :一个在同一类中,另一个在不同的类中 (面向对象)。

​即重载是函数名相同,参数列表不同 重载只是在类的内部存在;重写是子类重新定义父类中有相同名称和参数的虚函数,函数特征相同,但是具体实现不同,主要是在继承关系中出现的 。所以,重载和被重载的函数在同一类中;重写和被重写的函数在不同的类中,即分别位于基类和派生类中。

​②参数的区别 :一个参数列表一定不同,另一个参数列表一定相同。

​即重载和被重载的函数参数列表一定不同,重写与被重写的函数参数列表一定相同。

​③virtual的区别:一个可以有virtual修饰,也可以没有;另一个必须有virtual修饰。

​即重载函数和被重载函数可以被virtual修饰,也可以没有,重写的基类必须要有virtual修饰。
(2)重载、隐藏重写和的区别:

​①作用域区别: 重载的范围在同一类中;重写函数和被重写函数、隐藏函数和被隐藏函数均在不同类中。 ​ ②参数的区别: 隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定同;当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写。

总结:

​所以,想要区分这三个概念,可以关注它们概念的本质不同,再分别从作用域、参数等方面对区别进行细致比对,从而完成区别的总结。

http://www.lryc.cn/news/125848.html

相关文章:

  • 将非受信数据作为参数传入,可能引起xml 注入,引起数据覆盖,这个问题咋解决
  • 设计模式-简单工厂模式
  • Maven框架SpringBootWeb简单入门
  • 关于2023年8月19日PMP认证考试准考信下载通知
  • html实现iphone同款开关
  • 使用Vue和jsmind如何实现思维导图的历史版本控制和撤销/重做功能?
  • 【Vue-Router】路由元信息
  • vue 控件的四个角设置 父视图position:relative
  • VM中linux虚拟机配置桥接模式(虚拟机与宿主机网络互通)
  • 7.Eclipse中改变编码方式及解决部分乱码问题
  • grafana 的 ws websocket 连接不上的解决方式
  • 多环境_部署项目
  • go web框架 gin-gonic源码解读02————router
  • 【Java后端封装数据】常见后端封装数据的格式,用于返回给前端使用(109)
  • 无脑入门pytorch系列(三)—— nn.Linear
  • SQL Server用sql语句添加列,添加列注释
  • springBoot中service层查询使用多线程CompletableFuture(有返回值)
  • 畜牧虚拟仿真 | 鱼授精过程VR模拟演练系统
  • 第一百一十四回 局部动态列表
  • 多尺度目标检测【动手学深度学习】
  • elasticsearch 基础
  • 【BUG】docker安装nacos,浏览器却无法访问到页面
  • C#引用Web Service 类型方法,添加搜索本地服务器Web Service 接口调用方法
  • yolov8训练进阶:新增配置参数
  • 轻量级自动化测试框架WebZ
  • 如何实现安全上网
  • Redis心跳检测
  • 【数据库】Sql Server可视化工具SSMS条件和SQL窗格以及版本信息
  • Python SFTP 详细使用
  • MyBatis的XML映射文件