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))。

 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐