C++学习笔记:函数的重载与作用域

之前我讲了函数的重载相关的知识C++学习笔记:函数的重载

今天将以下关于重载的作用域
一般情况下,每一个版本的函数重载都应该在同一个作用域中声明
但是有种情况是:如果其中一个函数的声明做了一个局部的声明,那么这种情况就叫做‘函数屏蔽’,而不是函数的重载!!

在讲函数屏蔽(函数隐藏)之前,我们先来看一下变量屏蔽
如下例所示:

#include
#include
#include
#include
using namespace std;
string init()
{
	return "hello";
}

void fcn()
{
	int init = 0;//此时如果在该函数体中定义了一个和该函数中调用的某个函数重名的变量
	//注意这里的变量init和函数init()重名了
	string s = init();//此时如果在这里调用inti就会发生错误,此现象称之为“函数屏蔽”,该变量将外面的函数给隐藏(屏蔽)了
	cout << s << endl;
}
int main()
{
	fcn();//函数之间的相互调用
	
	system("pause");
}

我们可以从代码中看到,程序在执行的时候,在fcn这个局部函数中首先看到了init的变量,因此在该函数中往后就会把init函数当成变量,就相当于给它屏蔽了。


在此基础上我们再来看函数的屏蔽:

首先看看正常的重载操作如下所示:

#include
#include
#include
#include
using namespace std;
void print(const string &);
void print(double);
void print(int);//三个重载函数的声明

void fooBar(int ival)
{
	print("hello");//三个重载的函数会依据传入的实参的不同选择性的输出对应的结果
	print(ival);
	print(3.14);
}

int main()
{
	fooBar(4);
	system("pause");
}

void print(const string &s)//三个重载函数的定义
{
	cout << "string:" << s << endl;
}

void print(double d)
{
	cout << "double:" << d << endl;
}

void print(int i)
{
	cout << "int:" << i << endl;
}

输出结果为:
C++学习笔记:函数的重载与作用域_第1张图片
然后再来看看函数的屏蔽是怎么发生的:

void fooBar(int ival)
{

	void print(int);//这是一个局部的函数声明

	print("hello");//三个重载的函数会依据传入的实参的不同选择性的输出对应的结果
	print(ival);
	print(3.14);
}

如果我们在调用三个重载函数之前,在fooBar这个局部函数内部首先又重新声明了一个同名函数,那么程序在执行的时候看到这个局部声明的函数名之后,只会认出后面三个重载函数中的一个相同形参的函数,其余的函数都会被屏蔽掉,在最先的C++语言中会提示出错!因此这就失去了重载的作用!

因此

我们在使用函数重载的时候要特别注意,必须要把需要重载的函数的声明写在一起在同一个作用域中,要么都在全局,要么都在局部,要是在不同作用域就不会发生重载。
注意:局部地声明函数是一种非常不明智的做法,这里建议最好将函数的声明都统一写到头文件中,然后需要的时候直接include就行,所要注意的是不要重复调用,加上头文件保护符就行

你可能感兴趣的:(C++,C++学习笔记,C++学习笔记,C++)