左值引用、右值引用和参数传递
左值、右值与参数传递
导读:除指针类型外,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).避免复制
两个重要概念:
- 引用变量常常用于避免越过函数调用界限复制对象(不管是在函数调用中还是函数返回中)。
- 为了使用引用代替复制能够进行传递和返回,在函数声明和返回中是需要语法的。
5.参数传递问题
-
传值调用
-
传左值引用调用:
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); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!