POD 类型是一个神神道道的概念,有点反人类。好在大多时候我们并不需要涉及这个概念,即便在一些场景中用到了,C++11 新增的 3 个与之有关的判断也足够了。
概念
关于这个概念,在 C++11 之前使用了很多的限定来概括出它(貌似源于《imperfect c++》)。C++11 则给出了新的定义。关于其限定,我整理了 维基百科 - pod 得到下图:
这个其实是用思维导图软件 Mindjet 做的,原稿下载。用思维导图来整理 pod 的概念比 markdown 更合适。
表达式 | POD类型T | non-POD类型T |
---|---|---|
new T | 不初始化 | 缺省初始化 |
new T() | 缺省初始化 | 缺省初始化 |
new T(x) | 调用构造函数初始化 | 调用构造函数初始化 |
我们以最简单的 POD 类型(使用内置类型 int)进行举例:
1 | int i; // 分配内存,但不进行初始化,其内存块存储为“垃圾值” |
如果我们看到某个类型符合 POD 要求,进而通过二进制拷贝的方式简洁地实现其拷贝构造函数——这是不可行,是矛盾的。因为 POD 的概念要求之一是:没有用户定义的复制构造函数。
数组
数组不允许拷贝和赋值,这是常识。
合成拷贝构造函数
虽然我们不能直接拷贝一个数组,但合成拷贝构造函数会 逐元素地拷贝 一个数组类型的成员。如果数组元素是类类型,则使用元素的拷贝构造函数来进行拷贝。P441
合成拷贝赋值运算符
对于数组类型的成员,逐个赋值 数组元素。P444
结论:只使用了内置数值类型、char[]
的数据交换类,合成的拷贝构造函数、拷贝赋值运算符满足使用要求。无需显式定义拷贝控制函数。
C++11
关于 C++11 对 pod 的重新定义及相关函数,可以参考 C++11:POD数据类型 - csdn
1 | // 是否满足平凡的定义 |
用途
从实用性的角度来说,我们更应该关注 pod 类型的用途,而非强调其概念。一方面区分其概念很耗费心力;另一方面,我们已经看到 C++11 提供了函数,我们只需要调用就可以得到结果。我们将繁复的工作交给机器,从而解放头脑和双手。
POD通常被用在系统的边界处,即指不同系统之间只能以底层数据的形式进行交互,系统的高层逻辑不能互相兼容。
POD类型在源代码兼容于ANSI C时非常重要。POD对象与C语言的对应对象具有共同的一些特性,包括初始化、复制、内存布局、寻址。
POD类型是可以进行二进制拷贝的