导读:除指针类型外,C++还定义了引用类型。C++11的主要变化之一是新的引用类型的创建,叫右值引用(rvalue reference)。
1.左值与右值的区别- 一个左值(lvalue)是一个标识非临时性对象的表达式。
- 一个右值(rvalue)是一个标识临时性对象的表达式,或者是一个不与任何对象相联系的值(如字面值常数)。
对以下代码:
vector<string> arr(3);
const int x=2;
int y;
...
int z=x+y;
string str="foo";
vector<string> *ptr=&arr;
根据这些声明,arr、str、arr[x]、&x、y、z、ptr、(*ptr)[x]都是左值,x是一个不可修改的左值。一般来说,程序中的变量名就是一个左值;其中2、“foo”、x+y、str.substr(0,1)都是右值,因为它们都是字面值。
2.左值引用的声明格式C++语言的语法允许函数调用或运算( *** 作)符重载在返回值类型中指定为左值。左值引用的声明是通过在某个类型后放置一个符号&来进行:
string str="hello";
string &rstr=str; //rstr是str的另一个名字
rstr+='o'; //把str改成helloo
3.右值引用格式
C++11中,右值引用是通过在某个类型后放置一个符号&&而被声明的,右值引用与左值引用具有相同的特征,不同的是,右值引用可以引用一个右值(即临时变量)。
string str="hello";
string &&bad1="hello"; //合法
string &&bad2=str+""; //合法
string &&sub=str.substr(0,4); //合法
4.左值引用的用途
(1).给结构复杂的名称起别名
(2).范围for循环
如让一个vector对象所有的值都增1,用for循环实现:
for(int i=0;i<arr.size();++i)
++arr[i];
使用左值引用课简化代码:
for(auto &x:arr)
++x;
(3).避免复制
两个重要概念:
- 引用变量常常用于避免越过函数调用界限复制对象(不管是在函数调用中还是函数返回中)。
- 为了使用引用代替复制能够进行传递和返回,在函数声明和返回中是需要语法的。
-
传值调用
-
传左值引用调用:
void swap(double &a, double &b); //交换a和b,参数类型正确
- 传常量引用调用:
string randomItem(const vector<string> &arr); //返回arr中一个随机项
C++参数传递机制:** 对于小的不应被函数改变的对象,采取传值调用合适;对于大的不应被函数改变且复制代价昂贵的对象,采取传常量引用调用是合适的;对于所有可以被函数改变的对象,应采取传引用调用。**
//通过三次复制进行交换
void swap(vector<string>& x, vector<string>& y) {
vector<string> tmp = x;
x = y;
y = tmp;
}
//通过3次移动进行交换,std::move函数把任何左值(或右值)转换成右值
template<typename Object>
void mySwap(vector<Object>& a, vector<Object>& b) {
vector<Object> tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)