C++20: Trivial type, Standard-layout, POD, Aggregate
FEATURE | Trivial | Standard-layout | POD | Aggregate |
---|---|---|---|---|
default constructor | Y | Y | Y | Y |
default constructor (=default) | Y | Y | Y | N |
custom constructor | Y? | Y | Y? | N |
class member initializers | N | Y | N | Y |
virtual functions | N | N | N | N |
reference members | Y | N | N | Y |
private members | Y | Y | Y | N |
diff member access control | Y | N | N | N |
base class | Y | Y | Y | Y |
virtual inheritance | N | N | N | N |
non-static memebers in diff class | Y | N | N | Y |
recursive requirement | Y | Y | Y | N |
Trivial types
- 拥有编译器提供或显式默认的特定成员函数
- 占用连续的内存区域
- 可以有不同类型访问说明符的成员
也就是说:
- 具有平凡默认构造函数、平凡复制构造函数、平凡复制赋值运算符和平凡析构函数
用户提供带参数的构造函数是没有问题的
- 没有虚函数或虚基类
- 没有具有相应的非平凡构造函数/运算符/析构函数的基类
- 没有具有相应的非平凡构造函数/运算符/析构函数的类类型的数据成员
Standard-layout types
- 不包含 C++ 语言特有的特性,比如虚函数
- 所有的成员具有相同的访问权限
也就是说:
- 可以有用户定义的特殊成员函数
- 没有虚函数或虚基类
- 所有非静态数据成员具有相同的访问控制
- 所有非静态数据成员都是标准布局
- 任何基类都是标准布局
- 第一个非静态数据成员类型不能跟基类相同
- 满足以下条件之一:
继承链中只能有一个类有非静态数据成员
- 最派生类中没有非静态数据成员,并且没有超过一个基类具有非静态数据成员
- 没有包含非静态数据成员的基类
Plain Old Data
POD = Trivial + Standard-layout
- C 可以直接使用 C++ 编译的 POD,它们具有相同的内存布局 (Standard-layout);
- 支持静态初始化 (Trivial)。
Aggregate
聚合类型看作是其它类型的组合。
- 所有数据成员是
public
访问权限; - 不能有
virtual
函数; - 可以继承非聚合类型,但不能是虚继承(since C++17);
- 数据成员也可以是非聚合类型;
- 可以出现类内初始化;
- 不可以自定义构造函数,包括
default
构造。(since C++20)