POD 类型

POD 类型是一个神神道道的概念,有点反人类。好在大多时候我们并不需要涉及这个概念,即便在一些场景中用到了,C++11 新增的 3 个与之有关的判断也足够了。

概念

关于这个概念,在 C++11 之前使用了很多的限定来概括出它(貌似源于《imperfect c++》)。C++11 则给出了新的定义。关于其限定,我整理了 维基百科 - pod 得到下图:

POD 类型

这个其实是用思维导图软件 Mindjet 做的,原稿下载。用思维导图来整理 pod 的概念比 markdown 更合适。

表达式 POD类型T non-POD类型T
new T 不初始化 缺省初始化
new T() 缺省初始化 缺省初始化
new T(x) 调用构造函数初始化 调用构造函数初始化

我们以最简单的 POD 类型(使用内置类型 int)进行举例:

1
2
3
int i;    // 分配内存,但不进行初始化,其内存块存储为“垃圾值”
int i(); // 如果这种形式存在/正确的话,其执行默认初始化,赋值 someone
// 但事实上,语法上更倾向于将其解释成返回 int 的函数声明

如果我们看到某个类型符合 POD 要求,进而通过二进制拷贝的方式简洁地实现其拷贝构造函数——这是不可行,是矛盾的。因为 POD 的概念要求之一是:没有用户定义的复制构造函数。

数组

数组不允许拷贝和赋值,这是常识。

合成拷贝构造函数

虽然我们不能直接拷贝一个数组,但合成拷贝构造函数会 逐元素地拷贝 一个数组类型的成员。如果数组元素是类类型,则使用元素的拷贝构造函数来进行拷贝。P441

合成拷贝赋值运算符

对于数组类型的成员,逐个赋值 数组元素。P444

结论:只使用了内置数值类型、char[] 的数据交换类,合成的拷贝构造函数、拷贝赋值运算符满足使用要求。无需显式定义拷贝控制函数。

C++11

关于 C++11 对 pod 的重新定义及相关函数,可以参考 C++11:POD数据类型 - csdn

1
2
3
4
5
6
// 是否满足平凡的定义
std::is_trivial<A>::value
// 是否是标准布局
std::is_standard_layout<A>::value
// 是否是 pod 类型
std::is_pod<A>::value

用途

从实用性的角度来说,我们更应该关注 pod 类型的用途,而非强调其概念。一方面区分其概念很耗费心力;另一方面,我们已经看到 C++11 提供了函数,我们只需要调用就可以得到结果。我们将繁复的工作交给机器,从而解放头脑和双手。

POD通常被用在系统的边界处,即指不同系统之间只能以底层数据的形式进行交互,系统的高层逻辑不能互相兼容。

POD类型在源代码兼容于ANSI C时非常重要。POD对象与C语言的对应对象具有共同的一些特性,包括初始化、复制、内存布局、寻址。

POD类型是可以进行二进制拷贝的