IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++合成的构造函数 -> 正文阅读

[C++知识库]C++合成的构造函数

概念

默认构造函数:无任何实参,执行默认初始化1

  1. 如果存在类内的初始值,用它来初始化成员。
  2. 否则,默认初始化该成员。

合成的默认构造函数(Synthesized default constructor):编译器创建的构造函数1

  1. 只有当类没有声明任何构造函数时,编译器才会自动地生成默认构造函数。
  2. 可以使用 = default 要求编译器自动生成默认构造函数。

构造函数与拷贝控制

如果一个类(基类或派生类)没有定义拷贝控制操作,则编译器将为它合成一个版本2

合成的移动操作

如果一个类定义了自己的拷贝构造函数、拷贝赋值运算符或析构函数,编译器就不会为它合成移动构造函数和移动赋值运算符[^13.6.2节,P475]。

如果一个类定义了析构函数,即使它通过 = default 的形式使用了合成的版本,编译器也不会为这个类合成移动操作3

只有当一个类没有定义任何自己版本的拷贝控制成员,且它的所有数据成员都能移动构造或移动赋值时,编译器才会为它合成移动构造函数或移动赋值运算符[^13.6.2节,P476]。

合成的构造函数何时被定义为删除的?

移动操作永远不会隐式地定义为删除的函数。

如果[^13.6.2节,P476]我们显式地要求编译器生成 = default [7.1.4节,P237]的移动操作,且编译器不能移动所有成员,则编译器会将移动操作定义为删除的函数。除了一个重要例外,什么时候将合成的移动操作定义为删除的函数遵循与定义删除的合成拷贝操作类似的原则[13.1.6节,P449]:

  • 移动构造函数定义为删除的函数的条件是:有类成员定义了自己的拷贝构造函数且未定义移动构造函数,或者有类成员未定义自己的拷贝构造函数且编译器不能为其合成移动构造函数。移动赋值运算符的情况类似。
  • 如果有类成员的移动构造函数或移动赋值运算符被定义为删除的或不可访问的,则类的移动构造函数或移动赋值运算符也被定义为删除的。
  • 类似拷贝构造函数,如果类的析构函数被定义为删除的或不可访问的,则类的移动构造函数被定义为删除的。
  • 类似拷贝赋值运算符,如果有类成员是 const 或是引用,则类的移动赋值运算符被定义为删除的。

测试

#include <limits.h>
#include <stdio.h>

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class A {
  int id_;

 public:
  A() { printf("A()\n"); }
  // 如果有拷贝构造函数或拷贝赋值运算符,那么编译器不会自动合成移动构造函数
  A(const A& rhs) : id_(rhs.id_) { printf("A(const A& %d)\n", id_); }
  // A(A&& rhs) : id_(rhs.id_) { printf("A(A&& %d)\n", id_); }
  A(int id) : id_(id) { printf("A(%d)\n", id_); }

  ~A() { printf("~A(%d)\n", id_); }
};

int main() {
  // vector<unique_ptr<A>> vec;
  // for (int i = 1; i <= 10; i++) {
  //   vec.push_back(unique_ptr<A>(new A(i)));
  // }

  vector<A> vec;
  // TODO std::move 的机制是什么?
  // 可以查阅《C++ Primer 第五版 中文版》
  vec.push_back(std::move(A(10)));  // 这里还是调用的复制构造函数

  getchar();

  return 0;
}

参考

《C++ Primer 中文版 第五版》7.1.4节(P235)、7.5节(P257)、15.7节(P551)、18.1.3节(P689)和第 13 章都介绍了关于构造函数的知识[^]。


  1. C++ Primer 中文版 第五版,7.1.4节,P236. ?? ??

  2. C++ Primer 中文版 第五版,15.7节,P551. ??

  3. C++ Primer 中文版 第五版,15.7.1节,P552.
    [^]: ??

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-13 22:34:39  更:2022-04-13 22:50:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:25:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码