C++引用的使用场景

前言

        之前的文章描述了C++引用的语法和一些性质。但是还不能体现出引用的实际作用。所以在这里写一下引用的使用场景和它的优点。

一、引用作为函数参数

做输出型参数

        这里我们用经典的交换函数来作为举例对象。现在我们需要写一个函数实现a和b值的交换。

#include <iostream>
using std::cout;
using std::endl;

void Swap(int* a, int* b)
{
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

int main()
{
	int a = 1;
	int b = 2;
	Swap(&a, &b);
	cout << a << endl;
	cout << b << endl;
	return 0;
}

        当然上面我给出的是指针的写法。下面我再给出引用的写法。

#include <iostream>
using std::cout;
using std::endl;

void Swap(int* a, int* b)
{
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

void Swap(int& a, int& b)
{
	int tmp;
	tmp = a;
	a = b;
	b = tmp;
}

int main()
{
	int a = 1;
	int b = 2;
	//Swap(&a, &b);
	Swap(a, b);
	cout << a << endl;
	cout << b << endl;
	return 0;
}

        不难看出,使用引用的方法写起来更简洁,而且在调用函数的时候也不需要去取实参的地址就能实现改变实参的需求。

提高效率

二、引用作为返回值

提高效率

        引用作为返回值可以省去函数返回时产生的临时变量,从而提高效率。但是这也是有条件的,下面举例说明。

int Function1()
{
	int a = 0;
	a++;
	return a;
}

int Function2()
{
	static int a = 0;
	a++;
	return a;
}

int& Function3()
{
	static int a = 0;
	a++;
	return a;
}

int mian()
{
    int a1 = Function1();
    int a2 = Function2();
    int a3 = Function3();
    return 0;
}

        上面三个函数的输出结果都是相同的,但是在函数效率上是有区别的。

        Function1和Function2都是属于传值返回型函数。传值返回型函数就是函数在return以后函数的栈帧空间会被回收,属于这个函数栈帧空间的变量都会被回收,这时return返回的值a会赋值给一个临时变量达到保存返回值的作用,然后再把这个临时变量赋值给其他变量(int a1 = Function1)。

        但是注意,Function2中的static int a并没有在函数的栈帧空间中存放,而是在静态区。这意味着就算函数的栈帧空间被回收了这个变量a还是存在在静态区的。这时你是不是会想到,不去创建临时变量直接把a赋值给其他变量。但是编译器并没有这样做,它还是生成了一个临时变量。是否生成临时变量是取决于返回类型的,并没有根据返回变量去做更细的优化。

        Function3是引用返回型函数。引用返回型函数在return过后函数的栈帧空间会被回收,然后函数会对返回变量a进行引用,然后把变量a的别名赋值给a3。在这个过程中并没有创建临时变量,但是对返回变量a有要求。那就是就算函数栈帧空间回收了以后这个返回变量a还存在。Function3中对变量a使用了static修饰做到了这一点,其他方法还有全局变量,malloc等等。

        这个效率提升在返回变量是一个大返回值的时候尤其明显,可以省去复制粘贴的计算和内存还有时间。

读写返回值

        引用做返回值有一个很妙的功能,就是可以通过引用做返回值实现对返回值的读写。下面举例说明。

typedef struct MyStruct
{
	int capacity[10];
	int size = 0;
}MySt;

        我定义了一个结构体MySt。现在我要写一个函数对这个结构体中的第5个位置的值进行修改。

void ModifyMySt(MySt* ps, int pos, int a)
{
	ps->capacity[pos] = a;
}

int GetMySt(MySt* ps, int pos)
{
	return ps->capacity[pos];
}

int main()
{
	MySt S;
	ModifyMySt(&S, 5, 4);
	cout << GetMySt(&S, 5) << endl;
	return 0;
}

         传统C语言写法我已经写出来了,ModifyMySt函数实现修改,GetMySt函数实现读取。但是C++中使用引用作为返回值后可以变得更简单更巧妙。

int& MyStAt(MySt& S, int pos)
{
	 return S.capacity[pos];
}

int main()
{
	MySt S;
	//ModifyMySt(&S, 5, 4);
	//cout << GetMySt(&S, 5) << endl;
	MyStAt(S, 5) = 4;
	cout << MyStAt(S, 5) << endl;
	return 0;
}

         相信看到上面的引用代码,不用我多说各位也能明白引用的巧妙之处了。

总结

        任何场景下都可以使用引用作为函数参数,但是引用作为返回值只能用在函数栈帧空间回收后返回对象还存在的情况下使用。合理使用引用可以让我们的代码效率大大提升,且可读性良好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值