本文主要是介绍C++基础面试题 | C++的左值和右值是什么?有什么区别和应用?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
回答重点
什么是左值?什么是右值?
- 左值: 可以出现在赋值运算符的左边,并且可以被取地址,通常是有名字的变量。
- 右值: 不能出现在赋值运算符的左边,不可以被取地址,表示一个具体的数据值,通常是常量、临时变量。
区分左值和右值的核心在于有没有持久的地址
- 左值: 可以取地址并且有名字的东西就是左值。
- 右值: 不能取地址的没有名字的东西就是右值。
示例:
int a = b + c;
这里a
是左值,因为它有变量名,可以取地址,可以放到等号左边。而b + c
的返回值是右值(返回值是临时变量,临时变量具有常量属性),没有名字且不能取地址,所以&(b + c)
不能通过编译,也不能放到等号左边。int a = 4;
在这个语句中,a
是左值,因为它是一个有名字的变量,4
作为普通字面量是右值。
扩展知识
左值引用
可以理解为是对左值的引用。对于左值引用,等号右边的值必须可以取地址,如果不能取地址,则会编译失败,或者可以使用const引用形式,但这样就只能通过引用来读取输出,不能修改数组,因为是常量引用。
示例代码:
int a = 5;
int& b = a; // b是左值引用
b = 4;
int& c = 10; // error,10无法取地址,无法进行引用
const int& d = 10; // ok,因为是常引用,引用常量数字,这个常量数字会存储在内存中,可以取地址
右值引用
可以理解为是对右值的引用。即对一个临时对象或者即将销毁的对象的引用,可以利用这些临时对象内部的资源,用于构造其他对象(把将亡值内部资源转移出去)。
如果使用右值引用,那表达式等号右边的值需要是右值,可以使用std::move
函数强制把左值转换为右值。
示例代码:
int a = 4;
int&& b = a; // error, a是左值
int&& c = std::move(a); // ok
move之后相当于告诉编译器,a是右值(将亡值)了,在特别是在涉及到资源管理的情况下,可以将右值资源掠夺出来用于其他对象(器官捐献也是一个形象的例子),这就是移动语义。
移动语义在C++中非常有用,特别是在涉及到资源管理的情况下。以下是一个使用移动语义的场景示例,假设我们有一个它管理字符串的类。可以利用右值将会消亡的特性写出移动构造函数,直接使用右值对象内部的资源构造新对象,避免了右值资源的delete和新构造对象的new
class Info
{
private:char* _msg;public:Info(const char* msg = "None"):_msg(new char[100]){strcpy(_msg, msg);cout << "Info()" << endl;}~Info(){if (_msg){delete[] _msg;_msg = nullptr;}cout << "~Info()" << endl;}Info(Info&& info){_msg = info._msg;info._msg = nullptr;}};
左值引用和右值引用的使用场景
- 左值引用: 当你需要修改对象的值,或者需要引用一个持久对象时使用。
- 右值引用: 当你需要处理一个临时对象,并且想要避免复制,或者实现移动语义时使用。
这篇关于C++基础面试题 | C++的左值和右值是什么?有什么区别和应用?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!