🌟
😊😊😊
📝
风过无痕
忘川如斯
如日方升
策引千问
在C++中,左值(lvalue)和右值(rvalue)是表达式的两种基本分类,它们决定了表达式的结果在内存中的位置和状态。左值通常指的是具有持久状态的对象,它们有明确的内存地址,可以被多次赋值。而右值通常是临时的、没有持久状态的值,它们通常没有内存地址,或者其内存地址在表达式结束后就变得无效。
C++11引入了右值引用(rvalue reference),用T&&表示,作为对左值引用(lvalue reference,用T&表示)的补充。这一特性极大地增强了C++的表达能力,特别是在资源管理和性能方面。
// Play.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "test.h"
std::string foo() {
return std::string("Hello C++");
}
int main()
{
printPlay();
double pie_val = 3.14;
int int_val = 5;
bool bool_val = -100;
std::cout << pie_val << std::endl;
std::cout << int_val << std::endl;
std::cout << std::boolalpha;
std::cout << bool_val << std::endl;
int a = 100;
int& b = a;
std::cout << &a << std::endl;
std::cout << &b << std::endl;
std::cout << "--------------------------------------------" << std::endl;
// 绑定到右值的引用称之为右值引用
std::string&& tmp = foo(); // tmp是foo()返回的临时字符串的右值引用
}
右值引用是C++11新增的特性,它允许我们为右值(即临时对象或即将被销毁的对象)创建一个引用。这样,我们就可以对右值进行更复杂的操作,比如移动语义(move semantics)。
int&& c = 20; // c是整数字面量20的右值引用(但这种情况不常见,通常用于函数参数或返回值)
std::string foo() {
return std::string("Hello, World!"); // 返回的临时字符串是一个右值
}
std::string &&d = foo(); // d是foo()返回的临时字符串的右值引用
但请注意,直接绑定一个右值到右值引用(如int&& c = 20;)并不是右值引用的主要用途。右值引用的主要用途是作为函数参数(实现移动语义)和返回值(允许链式调用等)。
移动语义和完美转发
右值引用的引入主要是为了支持移动语义(move semantics),它允许我们在对象被销毁前“窃取”其资源(如动态分配的内存、文件句柄等),而不是进行深拷贝。这可以显著提高性能,特别是在处理大型对象或容器时。
完美转发(perfect forwarding)
另一个与右值引用相关的概念,它允许我们将参数原封不动地传递给另一个函数,无论是左值还是右值。这通过模板和std::forward函数实现。
总结
左值引用(T&)是C++98就有的特性,用于为已存在的对象创建别名。
右值引用(T&&)是C++11新增的特性,用于为右值(即临时对象)创建引用,支持移动语义和完美转发等高级特性。
右值引用的主要用途不是直接绑定到字面量或简单的右值表达式上,而是在函数参数和返回值中,以实现更高效的资源管理和更灵活的代码编写方式。