函数重载与引用

一、函数重载

在自然语言中,一个词可以有多个意思,人们可以根据上下文来分析它的意思,即该词被重载了。

函数重载:就是指在同一个作用域中,声明了几个作用不同但名称相同的函数。这些同名函数的参数个数,参数类型及参数类型的顺序不同。如:

1.1参数类型不同的函数

void Add(int a, int b)
{
	cout << "Add(int a, int b) = " << a + b << endl;
}
void Add(double a, double b)
{
	cout << "Add(double a, double b) = " << a + b << endl;
}
int main()
{
	Add(1, 2);
	Add(1.1, 1.2);
	return 0;
}

运行结果:ee10a0cfb9b14abda64821f39db3c472.png

1.2参数数量不同的函数

void F()
{
	cout << "F()" << endl;
}
void F(int a)
{
	cout << "F(a)" << endl;
}
int main()
{
	F();
	F(1);
	return 0;
}

运行结果:fe8c3d414ff049659c84487505c24b37.png

:在函数重载中使用缺省参数,应当注意一下情况。如:

void Func(int a, int b = 2)
{
	cout << "Func(int a, int b) = " << a + b << endl;
}
void Func(int a)
{
	cout << "Func(int a) = " << a << endl;
}
int main()
{
	Func(1,2);
	Func(1);
	return 0;
}

以上代码,编译器无法识别

1.3参数类型顺序不同的函数

void Func(int a, double b)
{
	cout << "Func(int a, double b) = " << a + b << endl;
}
void Func(double a, int b)
{
	cout << "Func(double a, int b) = " << a << endl;
}
int main()
{
	Func(1.1, 2);
	Func(1, 2.2);
	return 0;
}

运行结果:2e0a7bea576e4538922185d425335696.png

注:如果两个函数函数名和参数是一样的,但返回值的类型不同是无法构成重载的,因为调用时编译器无法区分。

二、引用

引用不是定义了一个新的变量,而是给已经存在的变量取了一个别名(也可以看做是外号、小名),编译器不会开辟新的内存空间,它们是公用了一块内存空间,只是名字不同。

引用的形式:类型& 引用对象名 = 引用实体

int main()
{
	int a = 0;
	int& b = a;//在这里&不是取地址,而是引用
	int& c = a;

	return 0;
}

在上述代码中,我们调试可以发现a,b,c的地址是相同的:

3e85ce9a09aa4e69999391fd2de8d745.png

因此,我们可以得出结论:只要上述名称中其中一个对象的值发生了改变,其他对象的值也会发生改变。

1.1引用的特性

  1. 引用在定义时必须初始化
  2. 同一个变量可以用多个引用
  3. 引用一旦引用了一个实体,就不能再引用其他实体了

1.2常引用

int main()
{
	const int a = 0;

    //从const int到int是权限的放大
	//int& b = a; //该语句编译时,会发生错误。由于a是常量,因此用非常量引用是非法的
    int d = a;//合法,因为这是赋值,不受权限的影响    

    //从const int到const int是权限的平移
    const int& b = a; //该语句合法
    
    int c = 0;
    const int s = c;//权限的缩小
	return 0;
}

权限可以缩小,权限可以平移,但权限不能放大

int main()
{
    int a = 0;
    double b = a;//语句合法
    double& b = a;//语句非法
    const double& c = a;//语句合法
}

上述代码第三句非法是由于,在C++中类型的转换并不是直接进行转换的,而是把a拷贝到一个临时变量中,再进行引用,由于临时变量是一个常量,因此第三句代码非法而第四句代码合法。如图:

a86d0bf335cc4ef196214a1fd47031ec.png

1.3引用的使用

1.1做参数

void Swap(int& p1, int& p2)
{
	int tmp = p1;
	p1= p2;
	p2= tmp;
	cout << "a = " << p1 << endl;
	cout << "b = " << p2 << endl;

}
int main()
{
	int a = 0;
	int b = 2;
	Swap(a, b);
	return 0;
}

运行结果:c6a11530ec294e05a335e830bea5d548.png

在C语言中,写Swap函数时需要用到指针,解引用。而在这里只需要用到引用,这是因为Swap参数表中的p1和p2引用的实体分别是实参a和b,由于是引用,因此p1和a指向的是同一块空间p2和b指向的是同一块空间,p1和p2发生改变则a和b就会发生改变。

1.2做返回值

struct SeqList
{
	int* a;
};
int& Push(int* a, int i)
{
	a[i] = i;
	return a[i];
}
int main()
{
	struct SeqList s;
	s.a = (int*)malloc(sizeof(int) * 5);
	Push(s.a, 0) = 0;
	Push(s.a, 1) = 10;
	Push(s.a, 2) = 20;
	cout << s.a[1] << endl;
	return 0;
}

运行结果:4ecaabb355914b65995562ebccb56ebb.png34075d8ad42740b4a1c736f47dc777c2.png

注:如果函数返回时,出了函数作用域,如果返回对象还存在(没有还给系统),则可以使用引用返回。但如果已经还给系统了,则必须使用传值返回。因为还给系统后,该函数的内存已经被释放。

1.4引用和指针的区别

引用在语法概念上就是一个别名,并没有独立的空间和它的引用实体共用一块空间。但在底层实现上,引用实际上是有空间的,因为引用是按照指针的方式实现的

引用和指针的不同之处:

  1. 引用在概念上定义一个变量的别名,指针存储一个变量地址
  2. 引用在定义时必须初始化,但指针并没有要求
  3. 引用在初始化时引用一个实体后就不能再引用其他实体,但指针可以在任何时候指向任何一个同类型的实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中,引用的结果是引用类型的大小,但指针始终是地址空间所占的字节数
  6. 引用比指针使用起来更加的安全
  7. 指针需要解引用,但引用是编译器自己处理

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值