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

C++中如何将含unique_ptr的对象移入vector避免报错

问题解答

持有std::unique_ptr成员的对象完全可以被移入同类型元素的std::vector容器,核心是使用C++移动语义,避免触发拷贝操作。

原理说明

std::unique_ptr是独占所有权的智能指针,它的拷贝构造函数、拷贝赋值运算符被显式删除,不支持拷贝操作,但原生支持移动语义。
只要你没有为类A显式删除移动构造/移动赋值运算符,也没有因为自定义拷贝操作、析构函数等逻辑导致编译器抑制默认移动语义生成,编译器会自动为A生成默认的移动构造和移动赋值函数,自动完成内部unique_ptr成员的所有权转移。

正确实现代码

直接使用std::move将待插入的左值对象转为右值,调用vector的push_back或者emplace_back触发移动插入即可:

#include <vector>
#include <memory>

// 前置声明someData类型,实际使用时替换为真实定义
struct someData;

class A
{
public:
   std::unique_ptr<someData> ptr;
};

int main() {
    std::vector<A> objects;
    A myObject;
    // 给myObject的ptr赋值,实际业务中替换为你的初始化逻辑
    myObject.ptr = std::make_unique<someData>();

    // 核心:用std::move转右值,触发移动语义插入
    objects.push_back(std::move(myObject));
    // 等价写法:objects.emplace_back(std::move(myObject));

    return 0;
}

关键注意事项

  • 移动操作完成后,原对象myObject处于有效但状态未指定的状态:它内部的ptr已经变为空指针,后续不要对myObject.ptr做解引用操作,否则会触发空指针访问错误。
  • 如果你为类A自定义了拷贝构造、拷贝赋值运算符、析构函数,编译器不会自动生成移动语义,此时需要手动实现移动构造和移动赋值运算符,示例:
class A
{
public:
   std::unique_ptr<someData> ptr;
   A() = default;
   ~A() { /* 自定义清理逻辑 */ }

   // 手动实现移动构造
   A(A&& other) noexcept : ptr(std::move(other.ptr)) {
       // 其他自定义成员的移动逻辑
   }

   // 手动实现移动赋值
   A& operator=(A&& other) noexcept {
       if (this != &other) {
           ptr = std::move(other.ptr);
           // 其他自定义成员的移动赋值逻辑
       }
       return *this;
   }
   // 拷贝操作显式删除,和unique_ptr的独占语义保持一致
   A(const A&) = delete;
   A& operator=(const A&) = delete;
};
  • 禁止直接对myObject做拷贝操作(比如直接写objects.push_back(myObject)),该操作会尝试拷贝内部的unique_ptr,直接触发编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:39:26