You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用右值引用时unique_ptr的所有权未发生转移?

为什么右值引用参数的std::unique_ptr未发生所有权转移?

要搞清楚这个问题,核心是理解std::unique_ptr的所有权转移逻辑,以及两种函数参数的本质区别:

1. 所有权转移的本质

std::unique_ptr的所有权转移,必须通过移动构造或移动赋值来完成——只有当你用一个右值unique_ptr去初始化另一个unique_ptr,或者赋值给它时,才会触发移动操作,把所有权从原对象转移到新对象。

2. 值传递参数的情况(第一种foo)

当foo的参数是std::unique_ptr<Myc> other(值传递)时:

  • 调用foo(std::move(pm))时,std::move(pm)将pm转换为右值引用;
  • 为了初始化函数参数other,编译器会调用unique_ptr的移动构造函数,把pm的所有权转移给other;
  • foo函数执行完毕后,局部变量other被销毁,连带销毁它所指向的Myc对象,所以输出顺序是End foo → Myc Destructed → End main。

3. 右值引用参数的情况(第二种foo)

当foo的参数是std::unique_ptr<Myc> &&other(右值引用)时:

  • std::move(pm)产生的右值引用,只是被绑定到了参数other上——other本质是原pm的一个"绑定别名",并没有创建新的unique_ptr对象;
  • 因为没有触发移动构造或移动赋值,所有权仍然属于pm;
  • foo函数执行完毕后,other作为引用不会销毁任何对象,直到main函数结束时pm被销毁,才会触发Myc的析构,所以输出顺序是End foo → End main → Myc Destructed。

验证:手动触发所有权转移

如果在第二种foo函数内部手动触发移动,所有权就会转移:

void foo(std::unique_ptr<Myc> &&other) { 
    std::unique_ptr<Myc> local = std::move(other); // 触发移动构造,转移所有权
    std::cout << "End foo\n"; 
}

此时local会接管所有权,foo结束时local销毁,析构信息会在End foo之后打印,和第一种情况的输出顺序一致。

内容的提问来源于stack exchange,提问作者rdabra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:02:50