c++的“The Rule of The Big Six”是什么? (C++20资源管理)
技术百科
裘德小鎮的故事
发布时间:2026-01-17
浏览: 次 The Rule of The Big Six指C++11起社区对六个关键特殊成员函数的统称:默认构造函数、析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符;手动定义其一通常需显式定义其余,以避免资源管理错误。
什么是 The Rule of The Big Six
“The Rule of The Big Six”不是 C++ 标准里的正式术语,而是社区对 C++11 起(尤其 C++20 强化后)六个关键特殊成员函数的统称:它们共同决定一个类如何管理资源。如果你手动定义了其中任何一个,大概率需要显式定义其余几个,否则容易引发浅拷贝、重复释放、移动后访问野指针等问题。
六个函数分别是什么
它们是:
-
default constructor(默认构造函数) -
destructor(析构函数) -
copy constructor(拷贝构造函数) -
copy assignment operator(拷贝赋值运算符) -
move constructor(移动构造函数) -
move assignment operator(移动赋值运算符)
注意: default constructor 有时被替换成 defa 或省略——真正核心是后五个。C++20 中,
= default 和 = delete 的语义更清晰,编译器对移动操作的隐式生成规则也更严格(比如:只要用户声明了任何拷贝/移动操作,编译器就不再自动生成移动构造/赋值)。
为什么不能只写析构函数就完事
常见错误场景:你写了 ~MyClass() 来 delete 原生指针,但没写移动或拷贝函数:
class BadExample {
int* data;
public:
BadExample() : data(new int[100]) {}
~BadExample() { delete[] data; } // ✅ 析构写了
// ❌ 没写 copy/move —— 编译器会合成默认的(逐成员复制)
};后果:
- 拷贝时
data被浅复制 → 两个对象指向同一块内存 → 双重delete[] - C++11 后,若没声明移动函数,编译器可能不生成移动版本 → 本可移动的场景被迫拷贝(性能损失)
- C++20 中,一旦你声明了
~BadExample(),编译器就不再隐式声明移动构造/赋值(即它们变成deleted),此时std::vector的push_back可能编译失败
实际怎么写才安全
优先用 RAII 容器(如 std::vector、std::unique_ptr),避免裸指针。如果必须管理原生资源,按需显式定义:
- 只读/不可拷贝类型 → 删除拷贝,保留移动:
BadExample(const BadExample&) = delete;、BadExample& operator=(const BadExample&) = delete; - 需要值语义(如
std::string)→ 实现深拷贝 + 移动窃取(std::swap或nullptr交换) - 想让编译器生成默认行为 → 显式写
= default(尤其移动函数在 C++20 中不会自动合成)
示例(安全且符合 C++20):
class GoodExample {
std::unique_ptr data;
public:
GoodExample() : data(std::make_unique(100)) {}
~GoodExample() = default; // ✅ unique_ptr 自动清理
// ✅ 默认拷贝/移动都可用(unique_ptr 禁止拷贝、允许移动)
GoodExample(const GoodExample&) = delete;
GoodExample& operator=(const GoodExample&) = delete;
GoodExample(GoodExample&&) = default;
GoodExample& operator=(GoodExample&&) = default;
};
真正麻烦的永远不是“要不要写六个”,而是“你是否意识到某个函数正被隐式删除,而你的容器或算法正依赖它”。C++20 把这种隐式行为收得更紧,反而更容易暴露问题——这不是限制,是提示你该检查资源契约了。
# ai
# 几个
# 意识到
# 如果你
# 写了
# 想让
# 你是否
# default
# go
# 对象
# c++
# String
# 指针
# 构造函数
# 为什么
# delete
# operator
# 成员函数
# 析构函数
# 算法
# 隐式
# 运算符
# 这不是
# const
# copy
# constructor
# 任何一个
# 赋值运算符
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Linux如何使用Curl发送请求_Linux下A
- 如何解决Windows时间不准的问题?(自动同步设
- Python配置文件操作教程_JSONINIYAM
- 如何使用Golang实现容器安全扫描_Golang
- 如何使用Golang recover捕获panic
- Win11怎么更改任务栏位置_修改注册表将Win1
- php485返回空数组怎么回事_php485数据接
- Win11怎么关闭应用权限_Windows11相机
- 如何在Golang中处理二进制数据_Golang
- LINUX如何删除用户和用户组_Linux use
- Win11怎么设置默认输入法 Win11固定中文输
- windows如何测试网速_windows系统网络
- Win11开机自检怎么关闭_跳过Win11开机磁盘
- 如何使用Golang实现Web表单数据绑定_自动映
- 如何在包含多值的列中精准搜索指定演员?
- Windows 11登录时提示“用户配置文件服务登
- Windows如何拦截腾讯视频广告_Windows
- Win10闹钟铃声怎么自定义 Win10闹钟自定义
- 如何有效拦截拼接式恶意域名的垃圾信息
- 如何在Golang中处理模块包路径变化_Golan
- Win11怎么设置任务栏图标大小_Windows1
- Windows怎样拦截QQ浏览器广告_Window
- Windows 11无法安全删除U盘提示设备正在使
- Windows笔记本无法进入睡眠模式怎么办?(电源
- c++ unordered_map怎么用 c++哈
- c++如何使用std::bind绑定函数参数_c+
- Win11麦克风没声音怎么设置_Win11麦克风权
- Mac如何修改Hosts文件?(本地开发与屏蔽网站
- Windows蓝屏BAD_POOL_HEADER故
- Windows10如何更改任务栏高度_Win10解
- MAC怎么解压RAR格式文件_MAC第三方解压工具
- Win11快速助手怎么用_Win11远程协助连接教
- C#如何使用Channel C#通道实现异步通信
- XAMPP 启动失败(Apache 突然停止)的终
- Mac如何彻底清理浏览器缓存?(Safari与Ch
- Win11怎么恢复出厂设置_Win11重置此电脑保
- Win11无法拖拽文件到任务栏怎么办_Win11开
- Windows怎样拦截WPS弹窗广告_Window
- Linux如何安装Tomcat应用服务器_Linu
- Win11怎样安装企业微信_Win11安装企业微信
- c++中的Tag Dispatching是什么_c
- Win11怎么开启上帝模式_创建Windows 1
- c++ std::atomic如何保证原子性 c+
- Win11应用商店下载慢怎么办 Win11更改DN
- Win11怎么设置组合键快捷方式_Windows1
- Win11怎么开启远程桌面_Win11系统远程桌面
- Bpmn 2.0的XML文件怎么画流程图
- Win11 C盘满了怎么清理 Win11磁盘清理和
- 如何在Golang中配置代码格式化工具_使用gof
- Windows10如何删除Windows.old_

QQ客服