引用的本质其实就是const指针,C++编译器在编译过程中使用使用常量指针作为引用的内部实现,因此引用所占的空间与指针相同。
而从使用者的角度来看,引用只是一个别名,它和原变量一样使用,而且它简单易用,可以避免操作指引带来的问题。
int main()
{
int y=10;
int &r = y; // r是y的引用
cout << r;
}
以上实例输出结果:
10
引用 | 指针 |
---|---|
引用必须在声明的时候就初始化 | 指针可以在任何时候初始化 |
只能初始化一次 | 可以被初始化无数次 |
不能有空引用 | 指针可以置为空 |
引用无需解引用 | 指针用*号解引用 |
引用通常用于函数参数列表和函数返回值,和指针一样。
下面我们通过一个简单的代码示例来学习 C++ 中引用的使用
int* first (int* x)
{
(*x++);
return x; // 安全,x在外部
}
int& second (int& x)
{
x++;
return x; // 安全,x在外部
}
int& third ()
{
int q;
return q; // 错误,函数结束时q的生命周期也跟着结束
}
int& fourth ()
{
static int x;
return x; // 安全,x是静态变量,因此它的生命周期一直存在
}
我们在上面的程序中有四个不同的函数。
q
并尝试返回一个它的引用,但是一旦函数 third() 结束,局部变量 q 就会被销毁,因此什么也没有返回。 常量引用用于函数参数中,以防止函数更改参数。
void g(const int& x)
{
x++;
} // 错误
int main()
{
int i=10;
g(i);
}
我们不能更改函数中的参数,因为它是作为 const 引用传递的。
通常在函数调用时使用 值传递只是为了防止我们的对象或变量被更改或修改,但是每当我们按值传递参数时,它的新副本就会被创建,如果我们将对象作为参数传递,那么会创建该对象的副本(调用构造函数和析构函数),这会影响效率。
因此,我们必须使用 const引用 类型的参数,当我们使用 const 引用时,只有一个地址在堆栈上传递,该地址在函数内部使用,并且函数不能更改我们的参数,因为它是 const 类型。
因此使用 const 引用类型参数即可以减少开销,又可以避免我们的参数被更改,这也是有经验的程序员经常使用的方法。