C++函数重载、函数重定义、以及函数重写

在C++的学习中,肯定免不了对一些概念的辨析,但往往很多时候,百思不得其解。问题的关键在于自己是否注意到了一些细节。

一、函数重载(overload)

函数重载是什么?
其实,我们大可以认为这是编译器的一种机制,他会根据函数的相关特性来自动对你所调用的函数进行匹配,自动选择匹配的函数,从而这种自动匹配选择从而调用对应的函数的机制,我们就可以称为函数重载。
怎么样能构成函数重载?

函数重载是指在一个类中声明多个名称相同但参数列表不同的函数,这些的参数可能个数或顺序,类型不同,但是不能靠返回类型来判断。特征是:
(1)相同的范围(在同一个作用域中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无(注:函数重载与有无virtual修饰无关);
注意:函数重载与返回值类型无关

下面,我就通过代码的形式来对函数重载进行说明:(我这里没有利用类来进行讲解,仅仅利用定义简单函数来讲解)

void sum(int a, int b)
{
    
    
	cout << "调用了参数类型int,int函数" << endl;
	cout << a + b << endl;
}

void sum(int a, int b, int c)
{
    
    
	cout << "调用了参数类型int,int,int函数" << endl;
	cout << a + b + c << endl;
}

void sum(char a, char b)
{
    
    
	cout << "调用了参数类型char,char函数" << endl;
	cout << (int)a + (int)b << endl;
}

void sum(char a, int b)
{
    
    
	cout << "调用了参数类型char,int函数" << endl;
	cout << (int)a + b << endl;
}
void sum(int a, char b)
{
    
    
	cout << "调用了参数类型int,char函数" << endl;
	cout << a + (int)b << endl;
}
#include<iostream>
using namespace std;
//程序入口
int main()
{
    
    
	sum(3, 4);
	sum(3, 4, 5);
	sum('a', 'b');
	sum('a', 3);
	sum(3, 'a');
	return 0;
}

运行结果如图:
在这里插入图片描述
通过运行的结果很显然,大家可以观察到,我明明调用的函数同名,但正是因为传入实参的个数,类型,顺序不同,它所调用的函数就不同,这就是重载。系统会根据你所传入实参的类型,个数,以及顺序,自动进行匹配,并调用相对应的函数,如果没有与之匹配的函数,则报错。

二、重定义(也称隐藏)

==注意:==我这里指的并非VS编译时,报错内容为重定义,此重定义非彼重定义,这里的重定义是指对函数进行重新的写入。这里我引用到类的概念了,如果大家对类的概念还不足够了解,那可以先转入其他的博主里面先了解类的概念,从而再来对重定义以及重写进行区分。
函数重定义是什么
(1)不在同一个作用域(分别位于派生类与基类) ;
(2)函数名字相同;
(3)返回值可以不同;
(4)参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载以及覆盖混淆);
(5)参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆);

#include<iostream>
using namespace std;
//基类
class Base
{
    
    
public:
	void Show()//无参
	{
    
    
		cout << "调用了基类Base类Show方法" << endl;
	}
private:

};
//派生类CA继承于Base类
class CA:public Base
{
    
    
public:
	void Show()//无参
	{
    
    
		cout << "调用了CA类Show方法" << endl;
	}

private:

};
//派生类CB集成与Base类
class CB:public Base
{
    
    
public:
	void Show(int i)//含参
	{
    
    
		cout << "调用了CB类Show方法" << endl;
	}
private:

};

//程序入口
int main()
{
    
    

	Base base;					//创建一个Base类对象
	base.Show();				//调用Show方法
	CA ca;						//创建一个Base类对象
	ca.Show();					//调用Show方法
	CB cb;						//创建一个Base类对象
	cb.Show(1);					//调用Show方法
	return 0;
}

运行结果:
在这里插入图片描述
可以看到,原本基类Base类中就存在了Show()方法。
假定我没有在派生类CA类去定义Show方法,则类对象ca必然调用的是基类的成员方法,具体实现,可以直接注释掉CA类里面的Show方法,运行即可,我就不在这里实现了。
但是在这,我在派生类CA中去重定义了Show方法,因此呢就隐藏了基类的Show方法那么类对象ca就会调用自己重写后的Show方法,所以类对象ca调用的是CA类的Show方法。
其次,CB类也对Show方法进行了重写,所以也隐藏了基类Show方法,此时CB的类对象cb就无法调用无参的Show方法了,cb只能调用自身重定义后的Show(int i)的方法了。
这就是函数重定义

三、重写(也称为覆盖 override)

函数重写是指子类重新定义基类的虚函数。特征是:

(1)不在同一个作用域(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有 virtual 关键字,不能有 static 。
(5)返回值相同,否则报错;
(6)重写函数的访问修饰符可以不同;

重载与覆盖的区别:

(1)覆盖是子类和父类之间的关系,是垂直关系;重载是同一个类中不同方法之间的关系,是水平关系;

扫描二维码关注公众号,回复: 12011319 查看本文章

(2)覆盖要求参数列表相同,重载要求参数列表不同;覆盖要求返回类型相同,重载则不要求;

(3)覆盖关系中,调用方法体是根据对象的类型(基类类型还是派生类类型)来决定的,重载关系是根据调用时的实参表与形参表来选择方法体的。

#include<iostream>
using namespace std;
//基类
class Base
{
    
    
public:
	virtual void Show(int a,int b)
	{
    
    
		cout << "调用了基类Base类Show方法并输出了两位数:"<<a<<","<<b << endl;
	}
private:

};
//派生类
class CA:public Base
{
    
    
public:
	void Show(int a, int b)
	{
    
    
		cout << "调用了基类CA类Show方法并输出了两位数:" << a << "," << b << endl;
	}

private:

};

//程序入口
int main()
{
    
    

	Base base;					//创建一个Base类对象
	base.Show(3,4);				//调用Show方法
	CA ca;						//创建一个Base类对象
	ca.Show(5,6);					//调用Show方法
	
	return 0;
}

运行结果:
在这里插入图片描述
注意:覆盖关系中,调用方法体是根据对象的类型(基类类型还是派生类类型)来决定的,重载关系是根据调用时的实参表与形参表来选择方法体的。
也就是说:调用函数时,是调用哪个函数,需要看类对象的类型。如果该类对象的类型为基类,则调用基类的成员函数,如果该类对象的类型为派生类,并且派生类对基类的成员函数进行了重写,则该派生类的类对象就会调用自己重写后的同名成员函数。

关于C++的学习,欢迎大家关注我,对我的文章进行评论,点赞,收藏,关注我不迷路。也欢迎广大网友跟我探讨C++的干货。C++的知识,远远不止这么点,我们一 一进行分析讲解。网友有什么想让我来进行讲解的,可以评论留言,我也会尽我所能给大家去做好讲解。

作者:ProMer_Wang

链接:https://blog.csdn.net/qq_43801020/article/details/106851972

本文为ProMer_Wang的原创文章,著作权归作者所有,转载请注明原文出处,欢迎转载!

猜你喜欢

转载自blog.csdn.net/qq_43801020/article/details/106851972