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
相关产品推荐
相关产品推荐

