std::unique_ptr不可复制只能移动,拷贝构造和赋值被删除;移交所有权需用std::move()标记为右值,此后源变为空,目标获得资源;函数传参或返回时应合理使用move,避免二次move等逻辑错误。

std::unique_ptr 不能复制,只能移动
这是所有问题的起点。如果你试图写 std::unique_ptr 或者传值给函数,编译器会直接报错:use of deleted function 'std::unique_ptr<_tp _dp>::unique_ptr(const std::unique_ptr<_tp _dp>&)'。因为 std::unique_ptr 的拷贝构造函数和拷贝赋值运算符都被显式删除了——它天生只允许一个指针拥有资源。
移交所有权必须用 std::move()
std::move() 不是真的移动内存,只是把左值“标记”为可移动的右值引用,从而触发 unique_ptr 的移动构造或移动赋值。没它,移交就卡死。
- 正确移交:
std::unique_ptr—— 此后p2 = std::move(p1); p1变成空(p1 == nullptr),p2持有原对象 - 函数返回时自动移动(C++11 起支持 RVO/NRVO,但显式
return std::move(p)一般不必要,甚至可能阻碍优化) - 传参给接受
std::unique_ptr值参数的函数时,调用方必须写func(std::move(p))
常见误用:对已空的 unique_ptr 再 move
不会崩溃,但容易引发逻辑错误。比如:
std::unique_ptrp = std::make_unique (42); auto p2 = std::move(p); // OK,p 现在为空 auto p3 = std::move(p); // 也编译通过,但 p3 是空的 —— 这不是你想要的“二次移交”
这种写法合法但无意义,p 已经释放了内部指针,再 std::move(p) 得到的仍是空 unique_ptr。真正要检查的是业务逻辑里是否误判了所有权状态。
立即学习“C++免费学习笔记(深入)”;
函数间传递 unique_ptr 的三种典型场景
移交不是目的,是配合资源生命周期管理的手段。关键看谁该负责释放:
- 工厂函数返回:直接
return std::make_unique,调用方自然获得所有权(...) - 函数获取并接管:参数声明为
void consume(std::unique_ptr,调用时写ptr) consume(std::move(ptr)) - 函数释放并交还:如果想让函数修改后还回所有权,返回类型用
std::unique_ptr,内部可安全移动局部变量或重新std::make_unique
别忘了:一旦移交,原变量不再持有资源,解引用前务必用 if (p) 或 p != nullptr 判断。











