在我原先写过的《c++——左值、右值、左值引用、右值引用》中有谈到引用。
简单来说,引用是参数的别名,不用额外开辟空间,节省开销。
举个例子:左值引用。
int _x = 0;
int &tmp = _x;
在C语言中,左值最初指的是可出现在赋值语句左边的实体,但这是引入关键字const之前的情况。
现在,常规变量和const变量都可视为左值,无非一个可修改,一个不可修改。
特殊点在于如下demo:
不同的是const + &可接收左值 和 右值。
int _x = 0;
int &tmp1 = _x;
int &tmp2 = 0; //错误
const int &rvalue1 = _x;
const int &rvalue2 = 0;
const + &的用处:
- 使用const可以避免无意中修改数据的编程错误
- 使用const使函数能够处理const和非const实参,否则将只能接受非const数据
- 使用const引用使函数能够正确生成并使用临时变量。
一、为何要返回引用
举个例子:
T & test1(T &x)
{
return x;
}
T test2(T &x)
{
return x;
}
void main()
{
T x, x1, x2;
x1 = test1(x);
x2 = test2(x);
}
test1函数 和 test2函数区别在于 一个 ”&”引用符号。
结果是:
test1 和 test2都执行了赋值运算符函数
而test2多执行了拷贝构造函数
原因在于,在返回的时候,需要构造一个临时对象tmp(隐式的),将x的内容赋给tmp
等价于T tmp(x)
可见带有引用的返回节省了开销。
二、返回引用需要注意的问题
切记引用返回的值需要是形参的值,不要返回局部的值,否则局部变量返回出去,会调用析构函数,再下次调用的时候出现奔溃。
三、为何将const用于引用返回类型
首先看个demo ,operator[]返回值加上引用&返回的是m_data[i]的数值,作为左值可以修改。
但是如果加上 const 修饰, 导致 b[1] = 100 不可用。
class B
{
public:
B() { for_each(m_data, m_data + 10, [](int &_data) {_data = 0; }); }
int & operator[](int i) { return m_data[i]; }
void print() { for_each(m_data, m_data + 10, [](int _data) {cout << _data << endl; }); }
private:
int m_data[10];
};
void main()
{
B b;
b.print();
b[1] = 100;
b.print();
system("pause");
}
也就意味着加上const 修饰 返回的是右值不可修改。