ZhiBing's blog(码上看世界) ZhiBing's blog(码上看世界)
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

ZhiBing Zheng

时间会回答成长
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • 编程语言

    • C++

      • shared_ptr(智能指针)
      • unique_ptr
      • bind函数
      • cout
      • C++ main函数的传入参数(argc, argv)
      • GLog使用
      • signals2
      • 编译期分派
      • 成员函数的调用效率
      • 返回值优化
      • 函数调用栈
      • 空类大小
      • 指针和数组的区别
      • 遵守三五原则
      • const限定符
      • static限定符
      • virtual限定符
      • 常用的CXX_FLAGS
      • 模版之AnyType
      • 模版之编译期断言
      • 模版之变参模板
    • Go

    • Python

    • shell

    • Rust

  • 调试

  • 开发者测试

  • 系统支撑

  • 性能优化

  • 通用领域
  • 编程语言
  • C++
zhengzhibing
2022-06-16

遵守三五原则

# 遵守三五原则

为什么要遵守三五原则?这涉及到 C++11 拷贝移动规则。

默认构造函数,析构函数,拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符。这些函数在需要的时候会被生成。

默认构造函数是当类中没有任何构造函数时才生成。

默认移动操作(移动构造函数,移动赋值运算符)如果生成了,会对非 static 数据执行逐成员的移动,也会移动基类部分。实际上是逐成员的移动请求,逐成员移动的核⼼是对对象使⽤std::move,然后函数决议时会选择执⾏移动还是拷⻉操作。

拷贝构造函数和拷贝赋值运算符是相互独立的,声明一个不会限制编译器声明另一个。

而移动构造函数和移动赋值运算符是互斥的,声明一个会限制编译器声明另一个。因为你声明了一个,就暗示你要自定义移动语义,不再按照逐成员方式进行移动。

另一方面,声明了拷贝操作,编译器就不会声明移动操作。声明拷贝操作暗示你逐成员拷贝方式不适合,也就是默认拷贝不适合,编译器就认为移动操作也是不适合的。

再者,声明了移动操作,编译器就不会声明拷贝操作。逐成员移动不适合,那不能要求逐成员赋值是适合的。

最后,用户定义了析构函数的,编译器也不会声明移动操作。

C++11 对于特殊成员函数处理的规则如下:

  • 默认构造函数:和 C++98 规则相同。仅当类不存在⽤⼾声明的构造函数时才⾃动⽣成。
  • 析构函数:基本上和 C++98 相同;稍微不同的是现在析构默认 noexcept(参⻅ Item14)。和 C++98 ⼀样,仅当基类析构为虚函数时该类析构才为虚函数。
  • 拷⻉构造函数:和 C++98 运⾏时⾏为⼀样:逐成员拷⻉⾮ static 数据。仅当类没有⽤⼾定义的拷⻉ 构造时才⽣成。如果类声明了移动操作它就是 delete。当⽤⼾声明了拷⻉赋值或者析构,该函数不 再⾃动⽣成。
  • 拷⻉赋值运算符:和 C++98 运⾏时⾏为⼀样:逐成员拷⻉赋值⾮ static 数据。仅当类没有⽤⼾定义 的拷⻉赋值时才⽣成。如果类声明了移动操作它就是 delete。当⽤⼾声明了拷⻉构造或者析构,该 函数不再⾃动⽣成。
  • 移动构造函数和移动赋值运算符:都对⾮ static 数据执⾏逐成员移动。仅当类没有⽤⼾定义的拷⻉ 操作,移动操作或析构时才⾃动⽣成。

这也是我们遵循三/五原则的原因。

三/五原则:

  • 三原则:析构函数,拷贝构造函数,拷贝赋值运算符
  • 五原则:析构函数,拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符
#C++
上次更新: 2022/06/17, 07:22:19
指针和数组的区别
const限定符

← 指针和数组的区别 const限定符→

最近更新
01
HPE gen10 plus 安装ESXI 7
06-12
02
ESXI 7安装黑群晖
06-12
03
ESXI 7安装win10
06-12
更多文章>
Theme by Vdoing | Copyright © 2022-2024 ZhBing Zheng | 粤ICP备2022062743号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式