左值引用
原创
1. 指针和引用
在C语言中,可以用指针变量保存变量的地址。在C++中,可以使用引用(Reference)直接引用某个变量。
引用给变量起了别名,它和它引用的变量共用同一块内存空间。在使用引用变量时,实际上是在引用原始的变量。
int a = 10;
int* pa = &a; // 指针
int& ra = a; // 引用
通过指针 pa
修改 a
。
*pa = 20;
通过引用 ra
修改 a
。
ra = 30;
引用可以用于更高效地函数传参。
// C swap
void swap(int* pa, int* pb) {
int temp = *pa;
*pa = *pb;
*pb = temp;
}
// C++ swap
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
// call C swap
int a = 10, b = 20;
swap(&a, &b);
// call C++ swap
int c = 30, d = 40;
swap(c, d);
return 0;
}
另外,和指针不同的是,引用在定义时必须初始化。且引用的变量不能被修改。
2. 常量引用
被 const
修饰的引用称为常量引用。
#include <iostream>
int main() {
int a = 10;
const int& const_ra = a;
std::cout << const_ra << std::endl; // 10
a = 20; // 修改a的值
std::cout << const_ra << std::endl; // 20
return 0;
}
常量引用可以对常变量进行引用,同时也可以对字面常量进行引用。
const int ca = 100;
const int& ra1 = ca; // 引用常变量
const int& ra2 = 200; // 引用字面常量
在函数传参时,可以使用常量引用接收各种类型的参数。
#include <iostream>
void func(const int& a) {
std::cout << a << std::endl;
}
int main() {
func(10); // 传入字面常量
int n = 20;
func(n); // 传入变量
const int c = 30;
func(c); // 传入常变量
return 0;
}
对于体积较小的变量,常量引用的方式传参和直接传参似乎没什么区别。但是如果是一个很大的对象(如结构体的对象),直接传参发生拷贝的开销很大,用常量引用可以优化对象拷贝的开销。关于这一点,将在之后类和对象章节提到。