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

C++创建含thread对象的自定义类vector报错的原因与解决方法

问题原因

你的AnalyzerCore类包含std::thread类型的成员,而std::thread是不可拷贝的类型——它的拷贝构造函数和拷贝赋值运算符被显式删除了。当类中存在不可拷贝的成员时,C++编译器会自动删除该类的拷贝构造函数和拷贝赋值运算符。

而vector::push_back在传入左值对象时,会尝试调用类的拷贝构造函数复制元素到容器中,这就触发了编译器的错误提示,因为拷贝构造函数已经被删除。

修复方案

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

std::thread支持移动操作,我们可以让AnalyzerCore类支持移动构造和移动赋值,这样就能通过移动方式将对象放入vector,避免拷贝。

代码示例:

#include <vector>
#include <thread>
#include <atomic>

class AnalyzerCore {
private:
    std::thread AnalyzerThread;
    std::atomic<bool> stopFlag{false}; // 安全停止线程的标记
    int id;

    void AnalyzerFunc() {
        while (!stopFlag.load()) {
            // 线程执行的业务逻辑
        }
    }

public:
    // 构造函数:初始化ID并启动线程
    explicit AnalyzerCore(int id_) : id(id_) {
        AnalyzerThread = std::thread(&AnalyzerCore::AnalyzerFunc, this);
    }

    // 析构函数:停止线程并等待结束
    ~AnalyzerCore() {
        stopFlag.store(true);
        if (AnalyzerThread.joinable()) {
            AnalyzerThread.join();
        }
    }

    // 显式默认移动构造函数(编译器可自动生成,显式声明更清晰)
    AnalyzerCore(AnalyzerCore&&) noexcept = default;
    // 显式默认移动赋值运算符
    AnalyzerCore& operator=(AnalyzerCore&&) noexcept = default;

    // 显式禁用拷贝构造和拷贝赋值(可选,编译器已自动删除,显式声明更明确)
    AnalyzerCore(const AnalyzerCore&) = delete;
    AnalyzerCore& operator=(const AnalyzerCore&) = delete;
};

int main() {
    std::vector<AnalyzerCore> analyzers;
    // 使用emplace_back直接在容器内存中构造对象,无需拷贝/移动
    analyzers.emplace_back(1);
    analyzers.emplace_back(2);

    // 若需先构造对象再放入容器,用std::move触发移动构造
    // AnalyzerCore a1(1);
    // analyzers.push_back(std::move(a1));
}

说明:

  • emplace_back直接在vector的内存空间中构造对象,是最高效的方式,完全避免了拷贝或移动操作。
  • 如果必须先构造对象再放入容器,用std::move将左值转为右值,触发移动构造而非拷贝。

方案2:存储智能指针

如果不想修改类的移动语义,可以在vector中存储std::unique_ptr<AnalyzerCore>或std::shared_ptr<AnalyzerCore>,容器操作的是指针,拷贝指针是允许的,不会涉及AnalyzerCore对象的拷贝。

代码示例:

#include <vector>
#include <thread>
#include <atomic>
#include <memory>

class AnalyzerCore {
private:
    std::thread AnalyzerThread;
    std::atomic<bool> stopFlag{false};
    int id;

    void AnalyzerFunc() {
        while (!stopFlag.load()) {
            // 线程执行的业务逻辑
        }
    }

public:
    explicit AnalyzerCore(int id_) : id(id_) {
        AnalyzerThread = std::thread(&AnalyzerCore::AnalyzerFunc, this);
    }

    ~AnalyzerCore() {
        stopFlag.store(true);
        if (AnalyzerThread.joinable()) {
            AnalyzerThread.join();
        }
    }

    // 显式禁用拷贝构造和赋值
    AnalyzerCore(const AnalyzerCore&) = delete;
    AnalyzerCore& operator=(const AnalyzerCore&) = delete;
};

int main() {
    std::vector<std::unique_ptr<AnalyzerCore>> analyzers;
    analyzers.push_back(std::make_unique<AnalyzerCore>(1));
    analyzers.push_back(std::make_unique<AnalyzerCore>(2));
}

说明:

  • std::unique_ptr是独占所有权的智能指针,适合无需共享对象的场景;若需共享对象,可改用std::shared_ptr。
  • 这种方式避免了对象的拷贝和移动,容器操作的是指针,灵活性更高,但需注意智能指针的所有权管理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 01:05:22