C++引用与构造:左值右值精讲
·
C++的左值引用、右值引用、移动构造与拷贝构造函数
1. 左值引用 (lvalue reference)
- 定义:绑定到有名称、持久存在的对象(左值)。通过
&声明。 - 特点:
- 必须初始化且不能更改绑定对象。
- 常用于函数参数传递,避免拷贝开销。
- 示例:
int a = 10; int& ref_a = a; // 左值引用绑定到变量a ref_a = 20; // 修改a的值
2. 右值引用 (rvalue reference)
- 定义:绑定到临时对象或即将销毁的对象(右值)。通过
&&声明(C++11引入)。 - 特点:
- 用于实现移动语义,高效转移资源所有权。
- 支持完美转发(
std::forward)。
- 示例:
int&& ref_temp = 42; // 绑定到字面量(右值) std::string&& s = get_string(); // 绑定函数返回的临时对象
3. 拷贝构造函数 (copy constructor)
- 定义:创建新对象时,复制另一个同类型对象的资源。
- 形式:
ClassName(const ClassName& other) - 特点:
- 深拷贝:复制所有资源(如动态内存)。
- 触发场景:传值参数、返回对象、初始化等。
- 示例:
class Vector { public: int* data; size_t size; // 拷贝构造函数(深拷贝) Vector(const Vector& other) : size(other.size) { data = new int[size]; std::copy(other.data, other.data + size, data); } };
4. 移动构造函数 (move constructor)
- 定义:直接“窃取”临时对象的资源,避免拷贝开销(C++11引入)。
- 形式:
ClassName(ClassName&& other) noexcept - 特点:
- 资源转移:直接接管
other的资源(如指针),并将other置为空状态。 - 高效性:适用于临时对象(右值),时间复杂度$O(1)$。
- 资源转移:直接接管
- 示例:
class Vector { public: // 移动构造函数(资源转移) Vector(Vector&& other) noexcept : data(other.data), size(other.size) { other.data = nullptr; // 置空原对象,避免双重释放 other.size = 0; } }; Vector v1 = create_vector(); // create_vector()返回临时对象,触发移动构造
关键对比
| 特性 | 拷贝构造 | 移动构造 |
|---|---|---|
| 参数类型 | const T& |
T&& |
| 资源处理 | 深拷贝(独立资源) | 转移资源(原对象失效) |
| 性能 | O(n)(可能昂贵) | O(1)(高效) |
| 适用场景 | 持久对象 | 临时对象(右值) |
使用场景示例
void process_data(const Vector& v); // 接受左值引用(避免拷贝)
void process_data(Vector&& v); // 接受右值引用(资源转移)
Vector v1;
process_data(v1); // 调用左值版本(拷贝构造)
process_data(Vector{1,2,3}); // 调用右值版本(移动构造)
总结:
- 左值引用优化参数传递,右值引用实现高效资源转移。
- 拷贝构造保证对象独立性,移动构造提升性能(尤其大型资源)。
- 结合
std::move可显式将左值转为右值(如return std::move(local_obj))。
更多推荐
所有评论(0)