来自cppreference.com
< cpp‎ | language

类是一种用户定义类型。

类的类型可以由类说明符定义,它在声明语法的 声明说明符序列 中出现。类说明符的语法参见类声明

类可以拥有下列种类的成员:

1) 数据成员:
2) 成员函数:
3) 嵌套类型:
a) 在类定义之中定义的嵌套类枚举
b) 既存类型的别名,以 typedef 类型别名 (C++11 起)声明定义
c)查找而言(除非在用作构造函数名时),类的名字在该类自身的定义中,表现为一个作为其自身的类型别名的公开成员:这被称作注入类名
4) 来自定义于类中的所有无作用域枚举,或由 using 声明using enum 声明引入 (C++20 起)枚举项
5) 成员模板变量模板、 (C++14 起)类模板或函数模板)可以在任何非局部 class/struct/union 定义体内出现。

所有成员都在类定义中一次性定义,不能向已定义的类添加成员(与命名空间成员不同)

T 的以下成员成员不能使用 T 作为它的名字:

  • 静态数据成员
  • 成员函数
  • 成员类型
  • 成员模板
  • 枚举的枚举项(除非该枚举为有作用域) (C++11 起)
  • 匿名成员联合体的成员

然而非静态数据成员可使用名称 T,只要没有用户声明的构造函数。

声明或继承了至少一个成员函数的类是多态的。此类型的对象是多态对象,并拥有作为其对象表示一部分存储的运行时类型信息,它可以通过 dynamic_casttypeid 查询到。虚成员函数参与动态绑定。

声明或继承了至少一个纯虚函数的类是抽象类。不能创建此类型的对象。

拥有 constexpr 构造函数的类是字面类型 (LiteralType) :此类型的对象能用 constexpr 函数在编译时进行操作。

(C++11 起)

类的性质

可平凡复制类

可平凡复制类 是满足以下所有条件的类:

平凡类

平凡类 是满足以下所有条件的类:


标准布局类

标准布局类 是满足以下所有条件的类:

  • 没有具有非标准布局类类型(或这种类型的数组)或到它们的引用的非静态数据成员
  • 没有虚函数虚基类
  • 所有非静态数据成员都具有相同的可访问性
  • 没有非标准布局的基类
  • 该类和它的所有基类中的非静态数据成员和位域都在相同的类中首次声明,并且
  • 非正式地说,该类的所有基类的类型均不同于第一个非静态数据成员。或者,正式来说,给定该类为 S,满足 M(S) 中没有 S 的基类,其中 M(X) 对于类型 X 定义如下:
  • 如果 X 是没有(可能继承来的)非静态数据成员的非联合体类类型,那么集合 M(X) 为空。
  • 如果 X 是首个非静态数据成员(可能是匿名联合体)具有 X0 类型的非联合体类类型,那么集合 M(X) 包含 X0 和 M(X0) 中的元素。
  • 如果 X 是联合体类型,集合 M(X) 是包含所有 Ui 的集合与每个 M(Ui) 集合的并集,其中每个 Ui 是 X 的第 i 个非静态数据成员的类型。
  • 如果 X 是元素类型是 Xe 的数组类型,集合 M(X) 包含 Xe 和 M(Xe) 中的元素。
  • 如果 X 不是类类型或数组类型,那么集合 M(X) 为空。


标准布局结构体 是以类关键词 struct 或类关键词 class 定义的标准布局类。标准布局联合体 是以类关键词 union 定义的标准布局类。

(C++11 起)

隐式生存期类

隐式生存期类 是满足以下条件之一的类:

  • 它是析构函数不由用户声明 (C++11 前)用户提供 (C++11 起)聚合体,或
  • 至少有一个平凡且合格的构造函数和一个平凡且未被弃置的析构函数。

注解:隐式生存期属性是由缺陷报告 P0593R6 明确的。

POD 类

POD 类 是满足以下所有条件的类:

  • 它是聚合体
  • 没有用户声明的复制赋值运算符,
  • 没有用户声明的析构函数,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 前)
  • 它是平凡类,
  • 它是标准布局类,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 起)


POD 结构体 是非联合体的 POD 类。POD 联合体 是满足 POD 类条件的联合体。

POD 属性的使用被弃用。用户代码应该期待或要求平凡或标准布局属性,或者它们两者。

(C++20 起)

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
CWG 148 C++98 POD 类不能包含指向成员的指针,即使它们自身就是 POD(标量)类型 移除此限制
CWG 383 C++98 POD 类可以包含用户声明的复制赋值运算符或析构函数,只要它们没有被定义 不允许包含它们
CWG 1363 C++11 同时有平凡和不平凡的默认构造函数的类可以是平凡类 它不是平凡类
CWG 1496 C++11 构造函数全部被弃置的类可以是平凡类 它不是平凡类
CWG 1672 C++11 有多个空基类的类可以是标准布局类 它不是标准布局类
CWG 1734 C++11 可平凡复制类不能有不平凡但被弃置的复制/移动构造函数和复制/移动赋值运算符 被弃置时可以不平凡
CWG 1813 C++11 有继承了非静态数据成员的基类的类不是标准布局类 它可以是标准布局类
CWG 1881 C++11 对于一个标准布局类和它的所有基类,无名位域
可以在声明了所有数据成员的类以外的类声明
所有非静态数据成员和位域
必须在同一个类首次声明
CWG 1909 C++98 成员模板的名字可以和它的类名相同 不能相同
CWG 2120 C++11 在确定标准布局类时,M(X) 的定义没有考虑到首个成员是数组的类的情况 在 M(X) 的定义中处理这种情况
CWG 2605 C++98 隐式生存期类的析构函数可以由用户提供 已禁止