当前位置: 首页 > news >正文

C++坑系列,C++ std::atomic 拷贝构造函数问题分析与解决方案

问题概述

在实现高并发日志系统时,遇到了一个典型的C++ std::atomic 拷贝构造函数被删除的编译错误:

error: use of deleted function 'logrotation::LogStatistics::LogStatistics(const logrotation::LogStatistics&)'
error: use of deleted function 'std::atomic<long unsigned int>::atomic(const std::atomic<long unsigned int>&)'

错误详细分析

错误根本原因

1. std::atomic 的设计原理

std::atomic 类型故意删除了拷贝构造函数和拷贝赋值操作符,这是有意的设计决策:

template<typename T>
class atomic {
public:atomic(const atomic&) = delete;            // 拷贝构造函数被删除atomic& operator=(const atomic&) = delete; // 拷贝赋值被删除// 只允许原子操作T load() const noexcept;void store(T value) noexcept;// ...
};
2. 为什么这样设计?

原子性保证

  • 拷贝操作无法保证原子性
  • 拷贝过程中可能发生数据竞争
  • 多个原子变量之间的拷贝不是原子操作

示例问题

std::atomic<int> a{10};
std::atomic<int> b{20};// 假设允许这样做(实际不允许)
a = b;  // 这个操作不是原子的!
// b的值可能在读取和写入a之间被其他线程修改

3. 具体错误位置分析

问题代码:
struct LogStatistics {std::atomic<uint64_t> total_logs{0};      // 原子类型std::atomic<uint64_t> sampled_logs{0};    // 原子类型std::atomic<uint64_t> dropped_logs{0};    // 原子类型// ...
};// 在函数中返回LogStatistics对象时触发错误
LogStatistics get_statistics() const {return statistics_;  // ❌ 尝试拷贝包含atomic的结构体
}
编译器错误流程:
  1. get_statistics() 尝试返回 LogStatistics 对象
  2. 返回操作需要调用拷贝构造函数
  3. LogStatistics 包含 std::atomic 成员
  4. std::atomic 的拷贝构造函数被删除
  5. 编译器报错:无法合成默认拷贝构造函数

✅ 解决方案实施

方案1: 自定义拷贝构造函数(推荐)

核心思路:使用原子操作的 load() 方法安全地读取值,这种方案没有拷贝构造aotmic,只是读取aotmic的值而已

struct LogStatistics {std::atomic<uint64_t> total_logs{0};std::atomic<uint64_t> sampled_logs{0};std::atomic<uint64_t> dropped_logs{0};std::unordered_map<LogLevel, uint64_t> level_counts;std::chrono::system_clock::time_point start_time;// 默认构造函数LogStatistics() : start_time(std::chrono::system_clock::now()) {}// ✅ 自定义拷贝构造函数LogStatistics(const LogStatistics& other) : total_logs(other.total_logs.load()),      // 原子读取sampled_logs(other.sampled_logs.load()),  // 原子读取dropped_logs(other.dropped_logs.load()),  // 原子读取level_counts(other.level_counts),         // 普通拷贝start_time(other.start_time) {}           // 普通拷贝// ✅ 自定义赋值操作符LogStatistics& operator=(const LogStatistics& other) {if (this != &other) {total_logs = other.total_logs.load();      // 原子写入sampled_logs = other.sampled_logs.load();  // 原子写入dropped_logs = other.dropped_logs.load();  // 原子写入level_counts = other.level_counts;start_time = other.start_time;}return *this;}
};

方案2: 移除原子性(不推荐)

// ❌ 不推荐:失去线程安全性
struct LogStatistics {uint64_t total_logs = 0;        // 普通类型,非线程安全uint64_t sampled_logs = 0;      // 普通类型,非线程安全uint64_t dropped_logs = 0;      // 普通类型,非线程安全// ...
};

方案3: 使用指针或引用(复杂)

// 返回引用而不是值
const LogStatistics& get_statistics() const {return statistics_;  // 返回引用,避免拷贝
}
http://www.dtcms.com/a/438578.html

相关文章:

  • 视频网站做板块栏目asp.net企业网站
  • 如何做超一个电子商务网站做网站有个名字叫小廖
  • Font Awesome Web 应用图标
  • 校企合作下的中医实训室:如何实现 “教学 - 就业” 无缝衔接?
  • Python学习之Day04学习(持久存储与推倒数据)
  • 3100. 换水问题 II
  • 南宁网站搜索引擎优化上海做网站的的公司有哪些
  • P1420 最长连号
  • 渠道推广代理郑州厉害的seo优化顾问
  • LangChain源码分析(八)- Document加载器
  • Day91 基本情报技术者 单词表27 AI基礎
  • 质量管理方法
  • 【ATBS with Python】QA Chap1 Python Basics
  • Java 之继承与多态
  • 建设局电话965559seo综合查询平台官网
  • 做网站分辨率多少wordpress调查问卷插件
  • 东莞网站关键词优化排名wordpress init
  • 淘客APP的联盟规则适配层设计:如何通过策略模式快速响应淘宝/京东/拼多多政策变动?
  • Java-140 深入浅出 MySQL Spring事务失效的常见场景与解决方案详解(2)
  • AI心理类APP测评:产品设计、技术实现及对独立开发者的启示
  • AI编程开发系统013-基于Vue+SpringBoot的“知语”花卉销售网站(源码+演示视频+讲解+lw)
  • 广州有几个区分别叫什么南京做网站优化哪家好
  • 【Jitsi Meet】阿里云Docker安装Jitsi Meet后的调整
  • 企业网站颜色手机做网站软件
  • php入门
  • 深圳网站搭建哪里好奎文建设局网站
  • 用织梦建设网站杭州公司官方网站制作
  • 数仓各层级设计总结
  • 8.设计模式-两阶段终止(优雅停机)
  • 那里网站建设好广东建设信息网三类人