C++中不能复制只能移动的类型

在 C++ 中,不能复制(Non-Copyable)但可以移动(Movable) 的类型通常是那些用于管理独占性资源的类。

这些类的设计目标是确保在任何给定时间,只有一个对象拥有该资源的所有权,从而防止资源被重复释放或发生混乱。

核心类型:独占性资源管理器

以下是 C++ 标准库中一些最重要、最常见的只能移动不能复制的类型:

1. 内存和资源所有权管理
类型 托管的资源 为什么不能复制?
std::unique_ptr 独占性地管理堆上的动态内存。 如果复制,两个指针将指向同一块内存。当其中一个析构时,内存会被释放,另一个指针将变成悬空指针(Dangling Pointer)。
std::fstream / std::ifstream / std::ofstream 文件句柄(File Handle)。 复制会导致两个对象试图管理同一个操作系统文件描述符,可能导致关闭两次或访问冲突。
std::thread 操作系统线程的执行上下文。 复制一个线程对象意味着创建两个对象来控制同一个系统线程的生命周期和同步点,这是逻辑上不允许的。
2. 并发和异步工具
类型 托管的资源 为什么不能复制?
std::mutex 互斥锁的底层系统资源。 如果复制,两个 mutex 对象将代表同一个锁,使得锁机制失效,无法保证互斥。
std::lock_guard / std::unique_lock std::mutex 的独占性锁定状态。 它们是 RAII 锁,复制会导致两个对象试图同时管理同一个锁,破坏了独占性。
std::promise 异步操作结果的共享状态 复制将导致两个 promise 实例可以对同一个共享状态设置结果,这会破坏"单次设置"的规则。
std::packaged_task 异步函数和其内部的 std::promise 它封装了 std::promise,因此也必须保证独占所有权,确保任务只被执行一次。
std::future 异步操作的获取句柄 虽然有些 future 实现可以复制(如 std::shared_future),但默认的 std::future 通常只能移动,因为它代表了对结果的独占性访问
3. C++20 同步原语
  • std::jthread :C++20 中的 RAII 线程,它自动 join,继承了 std::thread 不可复制的特性。

  • std::counting_semaphore / std::binary_semaphore:信号量的底层资源是独占的。

总结和设计原则

当你设计一个 C++ 类时,如果这个类管理着一个无法安全共享的底层资源(如操作系统句柄、网络套接字、文件描述符、内存块的所有权),那么你应该:

  1. 禁用拷贝构造函数和拷贝赋值运算符 (C++11/14/17 通常使用 = delete)。

  2. 实现移动构造函数和移动赋值运算符(将底层资源指针/句柄从源对象转移到目标对象,并清空源对象)。

通过这种设计,C++ 编译器强制执行了资源所有权的转移,保证了资源的生命周期安全,这是现代 C++ 编程中一个重要的设计范式。

相关推荐
2501_9475758010 小时前
计算机毕业设计之jsp开山车行二手车交易系统
java·开发语言·hadoop·python·信息可视化·django·课程设计
骑士雄师10 小时前
java面试题 4:鉴权
java·开发语言
时间的拾荒人11 小时前
C语言字符函数与字符串函数完全指南
c语言·开发语言
浆果020711 小时前
NanoTrack C++ — RK3588 实时目标跟踪
c++·目标跟踪·rk3588
ysa05103011 小时前
【并查集】判环
c++·笔记·算法
2501_9481069111 小时前
计算机毕业设计之基于jsp教科研信息共享系统
java·开发语言·信息可视化·spark·课程设计
持力行12 小时前
C/C++ 中的 char*:它标识数组吗?为什么能用下标访问?
c语言·c++
取经蜗牛12 小时前
Python 第一阶段完全指南:从零到第一个实用工具
开发语言·python
dog25012 小时前
从重尾到截断流量模型的演进
开发语言·php
qq_4017004113 小时前
Qt QSS 完全入门写出漂亮界面以及解决样式不生效问题
开发语言·qt