有了指针,让参数的传递方式不再仅限于值传递。当一个自定义变量所占空间较大的时候,使用值传递的方式效率太低,使用指针相当于只传递了一个地址,可以大大提升传参效率。
引用和指针比较类似,能达到和指针一样的效果,可以提升传参效率,既然有了指针,为什么还需要引用?原因分析如下:
- 引用最初被提出来,是为了支持运算符重载
- 引用初始化时需绑定一个初值,而且无法被修改,这就保证了引用指向的地址是有效的(不会存在类似于野指针、指针为空的情况)
目录
一、支持运算符重载
1、不使用引用
假设有一个结构体 Person,我们要重载运算符 > 来比较两个人的年龄。如果没有引用,要想实现运算符重载,只能像下面这样
struct Person
{
int age;
char name[10];
bool operator >(Person* p1) // 使用指针
{
return this->age > p1->age;
}
};
使用时看起来就特别奇怪,完全就像是在比较两个对象的地址大小。这种情况就存在歧义,为了避免这样的情况,大佬便提出了引用。
struct Person p1 = {10, "张三"};
struct Person p2 = {11, "张三"};
&p1 > &p2 // 比较地址? 还是比较年龄?
2、使用引用之后
我们在上面案例的基础上修改,改为引用之后如下:
struct Person
{
int age;
char name[10];
bool operator >(Person& p1) // 使用引用
{
return this->age > p1.age;
}
};
现在使用就不存在歧义了,而且使用方式就和内置类型是完全一样的
struct Person p1 = {10, "张三"};
struct Person p2 = {11, "张三"};
p1 > p2 // 比较年龄大小
&p1 > &p2 // 比较地址大小
二、保证指向地址是有效的
使用指针可能存在空指针、内存泄漏等问题,除此之外,可能你不经意间就修改了指针指向的地址。
// 野指针
int* pa;
*pa = 10;
// 内存泄漏(不主动释放)
int* pb = new int;
使用引用时便无需顾虑这些,引用在声明时就需要绑定一个初值,而且无法修改,这就避免了类似于野指针、不经意修改指针地址的问题。
int pb = 10;
int& pc = pb;