【C++学习笔记】 std::atomic 拷贝构造错误解析

发布于:2025-06-14 ⋅ 阅读:(15) ⋅ 点赞:(0)
std::atomic<int> flag_0x52 = 0;

以上代码报错如下:

public.cpp:55:18: Copying variable of type 
'std::atomic<int>' invokes deleted constructor 
xxatomic:200:2: 'atomic' has been explicitly marked deleted here

std::atomic<int> flag_0x52 = 0; 触发了 C++ 中 std::atomic 的拷贝构造函数被显式删除(deleted)的限制。以下是原因和解决方案:

错误原因

  1. std::atomic 不可拷贝
    std::atomic 的设计禁止拷贝构造和拷贝赋值(这些函数被标记为 = delete)。这是为了确保原子操作的独占性,避免意外复制破坏原子性。

  2. 初始化语法问题
    代码使用了拷贝初始化(copy-initialization):

    std::atomic<int> flag_0x52 = 0; // 尝试调用拷贝构造函数(实际不可用)

    虽然看起来是用 0 初始化,但编译器会尝试将其解释为 std::atomic<int> temp(0); flag_0x52 = temp;,进而触发拷贝操作。


解决方案

✅ 方法 1:使用直接初始化(推荐)

用圆括号 () 替代等号 =

std::atomic<int> flag_0x52(0); // 正确:调用构造函数而非拷贝构造
✅ 方法 2:使用大括号初始化(C++11 起)
std::atomic<int> flag_0x52{0}; // 正确:列表初始化,不涉及拷贝
✅ 方法 3:分步初始化
std::atomic<int> flag_0x52; // 默认构造(值为0) // 或后续赋值

flag_0x52 = 42; // 调用operator=,合法

关键原则

  • 避免任何形式的拷贝:包括函数传参、返回值、容器操作等。需要传递时使用引用或指针。

  • 初始化用 () 或 {}:确保直接调用构造函数而非触发拷贝。

错误示例修正

// 错误:尝试拷贝构造

std::atomic<int> a = 10; // ❌

std::atomic<int> b = a; // ❌ 显式拷贝

// 正确:直接构造

std::atomic<int> a(10); // ✅

std::atomic<int> b(a.load()); // ✅ 先读取值再构造(非拷贝原子对象本身)

提示:检查代码中其他可能涉及 std::atomic 复制的场景(如函数传参 void foo(std::atomic<int>) 需改为 void foo(std::atomic<int>&))。


网站公告

今日签到

点亮在社区的每一天
去签到