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

C++中使用std::atomic时如何规避拷贝与移动构造函数相关编译报错

C++类含std::atomic成员无法存入std::vector的可行解决方案

编译报错的核心原因是std::atomic<T>删除了拷贝构造/拷贝赋值运算符,导致包含该类型成员的类A被隐式删除了拷贝构造/拷贝赋值,而std::vector<T>::push_back默认需要调用拷贝构造,因此触发编译错误。以下是几种不破坏线程安全的可行解决方案:

方案1:手动实现类A的拷贝/移动语义(最推荐,不改变存储结构)

std::atomic的默认拷贝被删除只是禁止了不安全的按字节拷贝,你可以手动实现拷贝逻辑,拷贝过程中使用原子读load()、原子写store()操作,完全不会破坏原子性:

所谓「封装结构体破坏原子性」是错误操作导致的问题:只要不直接对std::atomic内存做非法memcpy、直接按字节复制等操作,通过原子接口读写的实现是完全线程安全的。

class A {
private:
    std::atomic<bool> flag;    
    std::atomic<int> value;
public:
    A() = default;
    // 手动实现拷贝构造
    A(const A& other) : 
        flag(other.flag.load(std::memory_order_acquire)),
        value(other.value.load(std::memory_order_acquire)) {}
    // 手动实现拷贝赋值
    A& operator=(const A& other) {
        if (this != &other) {
            flag.store(other.flag.load(std::memory_order_acquire), std::memory_order_release);
            value.store(other.value.load(std::memory_order_acquire), std::memory_order_release);
        }
        return *this;
    }
    // 可选实现移动构造,支持移动语义避免拷贝开销
    A(A&& other) noexcept :
        flag(other.flag.load(std::memory_order_acquire)),
        value(other.value.load(std::memory_order_acquire)) {}
};

手动实现后原有push_back逻辑可以正常使用。

方案2:vector存储智能指针,避免A对象拷贝

如果不想修改类A的实现,可以将vector的存储类型改为std::unique_ptr<A>或std::shared_ptr<A>,仅拷贝指针而不触碰A的拷贝逻辑:

class B {
private:
    std::vector<std::unique_ptr<A>> vett;
public:
    B() = default;
    void add_A(std::unique_ptr<A> a) {
        vett.push_back(std::move(a));
    }
    // 也可以直接在方法内构造A对象
    void add_new_A() {
        vett.emplace_back(std::make_unique<A>());
    }
};

// 调用示例
int main() {
    B b{};
    b.add_A(std::make_unique<A>());
    return 0;
}

该方案的缺点是多了一层堆内存分配开销,适合A对象较大、拷贝成本高的场景。

方案3:原地构造对象避免拷贝

如果不需要存入外部构造好的A对象,仅需要在vector内部生成A实例,可以用emplace_back原地构造,完全不需要调用拷贝/移动构造:

class B {
private:
    std::vector<A> vett;
public:
    B() = default;
    void add_A() {
        // 直接在vector分配的内存上构造A,无拷贝开销
        vett.emplace_back();
    }
};

该方案适合不需要外部传入A实例的场景,改动最小性能最高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:06:06