信息发布→ 登录 注册 退出

C++中的移动构造函数和移动赋值运算符是什么?(右值引用)

发布时间:2025-12-16

点击量:
移动构造函数和移动赋值运算符是C++11引入的资源转移机制,通过右值引用“偷取”临时对象资源,避免深拷贝;需置原对象为可析构状态,推荐声明noexcept以支持容器高效扩容。

移动构造函数和移动赋值运算符是 C++11 引入的机制,用来避免不必要的深拷贝,提升资源管理效率。核心在于“偷走”临时对象(右值)所拥有的资源,而不是复制它。

移动构造函数:用右值“初始化”新对象

它接收一个右值引用参数(T&&),把源对象的内部指针、句柄等资源直接转移过来,再把源对象置为有效但可析构的状态(比如指针设为 nullptr)。

例如:

class String {
    char* data_;
public:
    // 移动构造函数
    String(String&& other) noexcept 
        : data_(other.data_) {  // “偷”指针
        other.data_ = nullptr;  // 源对象清空,防止析构时释放
    }
};

常见触发场景:返回局部对象、std::move() 显式转换、函数参数是右值引用时绑定临时对象。

移动赋值运算符:用右值“替换”已有对象的内容

它也接受 T&& 参数,先释放当前对象已持有的资源(如 delete[] data_),再接管右值的资源,并同样将右值“掏空”。

关键点:

  • 通常要自检(if (this != &other)),虽然右值一般不会自赋值,但写上更稳妥
  • 建议加 noexcept,否则容器(如 std::vector)在扩容时可能退回到拷贝而非移动
  • 移动后原对象必须处于可安全析构的状态

右值引用(T&&)不是“只能绑定右值”

它本质是一种类型,能绑定右值,但也能通过 std::move() 把左值“转成右值引用语义”。std::move 不移动任何东西,只是类型转换——告诉编译器:“我允许你对这个对象做移动操作”。

比如:

String a = "hello";
String b = std::move(a); // 此时调用移动构造函数,a变成空状态

移动操作被自动调用的条件

编译器会在确定源对象是“将亡值”(xvalue)或纯右值(prvalue)时,优先选择移动而非拷贝,前提是:

  • 类定义了移动构造函数/移动赋值运算符(或没显式删除)
  • 对应函数未被声明为 delete 或不可访问
  • 移动操作是 noexcept(对移动赋值尤其重要)

如果没定义移动函数,编译器会退回到拷贝;如果只定义了移动构造但没定义移动赋值,赋值仍走拷贝赋值(如果存在)。

基本上就这些。移动语义不是魔法,本质是资源所有权的转移,写的时候注意资源释放、空状态处理和异常安全性。

标签:# this  # 你对  # 会在  # 设为  # 也能  # 已有  # 句柄  # 是一种  # 而非  # 绑定  # c++  # 对象  # 类型转换  # delete  # 引用参数  # 指针  # 构造函数  # if  # 赋值运算符  # 运算符  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!