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

类含unique_ptr的deque成员时,向类对象vector插入报错原因咨询

问题原因与解决方案:含unique_ptr成员的类存入vector报错

错误核心原因

你的代码无法运行,是因为**std::unique_ptr是独占所有权的智能指针,完全不支持拷贝操作**。

当执行myVector.push_back(MyClass(5))时,流程是这样的:

  1. 先创建一个临时的MyClass(5)对象,它的myDeque成员里已经存了一个unique_ptr<int>。
  2. push_back会尝试把这个临时对象拷贝到vector的内存里,但MyClass的默认拷贝构造函数是逐成员拷贝的——也就是要拷贝整个myDeque,而deque里的每个unique_ptr都不能被拷贝,直接触发编译错误。

至于全局myDeque能运行的原因很简单:全局变量不属于类成员,MyClass拷贝时不会碰它,自然不会触发unique_ptr的拷贝冲突。


解决方案

方案1:启用移动语义(推荐)

unique_ptr支持移动操作(把所有权转移给另一个对象),我们可以让MyClass启用移动构造和移动赋值,同时禁用拷贝操作避免误触发:

#include <vector>
#include <deque>
#include <memory>

class MyClass {
public:
    MyClass(int x) {
        myDeque.push_back(std::unique_ptr<int>(new int(x)));
    }
    // 显式启用默认移动构造/赋值
    MyClass(MyClass&&) = default;
    MyClass& operator=(MyClass&&) = default;
    // 禁用拷贝构造/赋值,防止意外触发错误
    MyClass(const MyClass&) = delete;
    MyClass& operator=(const MyClass&) = delete;
private:
    std::deque<std::unique_ptr<int>> myDeque;
};

int main() {
    std::vector<MyClass> myVector;
    // 临时对象会被移动到vector中,而非拷贝
    myVector.push_back(MyClass(5));
    // 更高效的写法:直接在vector内存里构造对象
    myVector.emplace_back(6);
}

方案2:用emplace_back直接构造对象

emplace_back可以跳过临时对象的创建,直接在vector的内存空间里构造MyClass,从根源避免拷贝/移动操作(当然配合移动语义会更稳妥):

int main() {
    std::vector<MyClass> myVector;
    // 直接在vector内部构造MyClass,无临时对象
    myVector.emplace_back(5);
}

补充:如果需要拷贝类对象怎么办?

如果你的业务场景确实需要拷贝MyClass,那unique_ptr就不适用了,可以换成std::shared_ptr——它支持共享所有权,允许拷贝操作,但这会改变资源的管理逻辑,需要根据实际需求判断是否合适。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:02:29