一、引用的基本概念
引用在本质上就是指针, 只要与指针用法相对照,就很容易理解了
指针类型
int*
double*
Object*
// 指针定义
// 称作:“p指向了变量a”
int a = 123;
int* p = &a;
*p = 888;
引用类型
int&
double&
Object&
// 引用定义
// 称作:“r是目标对象a的引用”
// r引用了目标对象a
int a = 123;
int& r = a; // 引用的定义
r = 999; // 对r的操作,就是对a的操作, 则目标对象a变成了999
printf("%p", &r); // 打印的是目标对象a的地址
引用可以看作是目标对象的一个别名,对引用的操作其实都是对目标对象的操作
使用举例
struct Object
{
int id;
char name[16];
};
Object a = {1, "shaofa"};
Object& r = a;
r.id = 2; // 访问目标对象
strcpy(r.name, "xyz"); // 访问目标对象
二、注意事项
引用必须在定义的时候初始化
,也就是一创建就要与目标对象绑定
// 以下代码有语法错误:
int a = 123;
int& r; // 语法错!必须初始化!
r = a;
// 相比之下,指针的用法则比较宽松
int a = 123;
int* p; // OK, 指针可以不初始化
p = &a;
三、引用的更多用法
- 引用作为函数的参数
- 引用作为函数的返回值
引用作为函数的参数
和指针类似,引用也可以作为函数的参数,功能相同
“传引用”和“传地址”本质相同
void test (int& a)
{
a = 999;
}
int main()
{
int number = 0;
test(number);
return 0;
}
所以,参数的传递有两种方式:
- 传值 (效率低)
- 传地址或传引用 (效率高)
引用作为函数的返回值
和指针一样,引用也可以作为函数返回值
int number = 0; // 全局变量
int& test()
{
int& a = number;
return a; // 返回引用
}
int main()
{
int& r = test();
r = 123; // 修改目标对象的值
return 0;
}
也可以简化如下:
int number = 0; // 全局变量
int& test()
{
return number; // 此处作了简化
}
⚠️ return number:
并不是返回了number的值,而返回了它的引用
返回值作为左值
int main()
{
test() = 123;
return 0;
}
注:普通函数的返回值都只是右值,只有返回引用时才能当做左值来用(不过可读性不高)
三、安全问题
和指针一样,引用也有安全性问题
主要是检查:引用的目标对象是否有效?
比如,以下引用的目标对象是一个局部变量,那么,在函数退出后,目标对象失效,所以引用也就不能再用了
int& test()
{
int target = 123;
return target;
}
网友评论