C++中的POD类型
参考
https://en.cppreference.com/w/cpp/named_req/PODType
定义
知识的搬运工,以下内容抄的,虽然是硬性定义,但是希望大家要深刻理解与体会。 POD类型具体要求满足如下条件:
- 标量类型
- 满足下列要求的类类型:
- 为平凡类型, 即要求满足如下条件:
-
可平凡复制 (TriviallyCopyable),即满足如下条件:
-
标量类型
-
可平凡复制类类型,即满足下列条件的类类型:
- 至少一个复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符是合格的
- 每个合格的复制构造函数(若存在)均为平凡的
- 每个合格的移动构造函数(若存在)均为平凡的
- 每个合格的复制赋值运算符(若存在)均为平凡的
- 每个合格的移动赋值运算符(若存在)均为平凡的
- 拥有一个平凡而未弃置的析构函数
- 可平凡复制 (TriviallyCopyable) 对象的数组
满足以上条件,意味着平凡复制类没有虚函数或虚基类。
-
-
若该类型是类类型或其数组,则该类拥有一个或多个合格的默认构造函数,均为平凡的。
- 一个默认构造函数为合格当且仅当它不是弃置的。
-
- 为标准布局类型,即要求:
- 所有非静态数据成员必须具有相同的访问控制
- 没有虚函数或虚基类
- 没有引用类型的非静态数据成员
- 所有非静态数据成员和基类自身也是标准布局类型
- 不存在两个相同类型的(可能间接的)基类子对象
- 所有非静态数据成员和位域都在同一类中声明(要么全在派生类中,要么全在某个基类中)
- 不存在与如下各项具有相同类型的基类子对象
- 对于非联合类型,为其首个非静态数据成员(见空基类优化),递归地,若该数据成员具有非联合类类型,则为其首个数据成员,或者若该数据成员为联合体类型,则为其所有非静态数据成员,或者若该数据成员为数组类型,则为其元素类型,依此递归。
- 对于联合体类型,为其任何非静态数据成员,递归地,若该数据成员具有非联合类类型,则为其首个数据成员,或者若该数据成员为联合体类型,则为其所有非静态数据成员,或者若该数据成员为数组类型,则为其元素类型,依此递归。
- 对于数组类型,为数组元素的类型,递归地,若该数据成员拥有非联合类类型,则为其首个数据成员,或者若该数据成员为联合体类型,则为其所有非静态数据成员,或者若该数据成员为数组类型,则为其元素类型,依此递归。
- 没有非 POD 的非静态成员
- 为平凡类型, 即要求满足如下条件:
- 这种类型的数组
总结与理解
- 从最终根本上讲,POD类型,保证了与C语言类型兼容,能直接以其二进制形式与 C 库交互。
- 要满足非凡类型,是因为:保证了对象可以进行复制,并且对一个对象二进制拷贝后,该对象的全部属性都被copy了。
- 要满足标准布局,是因为:保证该数据结构可以与其他语言编写的代码交流。大家风格一致,是最平凡的布局。 不会因为一些语言特性导致内存布局有差异。例如c++的虚函数、多继承等会导致由于虚表指针和多个基类之间的字节对齐引起的内存布局有差异。