##什么是PODs以及它的特殊性 在C++标准中的正式定义(C++03 9 §4):c++
一个POD结构体是一个没有非静态的non-POD-struct、non-POD-union(或者这些类型的数组)或者引用类型的数据成员的aggregate类型,而且没有用户自定义的拷贝赋值操做和用户自定义的析构函数(译者注:这句话读起来很绕,在此解释一下,POD类型首先是一个aggregate类型,这个aggregate类型中不能含有非静态的non-POD结构体或者联合体,也不能含有用户自定义的拷贝赋值函数和用户自定义的析构函数)。相似的,一个POD联合体是一个没有非静态的non-POD-struct、non-POD-union(或者这些类型的数组)或者引用类型的数据成员的aggregate类型,而且没有用户自定义的拷贝赋值操做和用户自定义的析构函数。一个POD类要么是POD结构体,不然是POD联合体。
这个看起来更难以理解。如今让咱们把联合体剥离,换一种更清晰的说法:数组
若是一个aggregate类型不含用户自定义的拷贝赋值函数和析构函数,不含有非静态的non-POD类型的结构体和no-POD类型结构体的数组,不含有引用成员,则这个aggreagate类型为POD类型。
这个定义是什么意思呢(POD就是Plain Old Data)?安全
举例:函数
struct POD { int x; char y; void f() {} //no harm if there's a function static std::vector<char> v; //static members do not matter }; struct AggregateButNotPOD1 { int x; ~AggregateButNotPOD1() {} //user-defined destructor }; struct AggregateButNotPOD2 { AggregateButNotPOD1 arrOfNonPod[3]; //array of non-POD class };
POD类、POD联合体、标量类型以及上述全部类型的数组被统称为POD类型。 PODs有不少特殊的地方,我这里仅举几个例子:布局
memcpy
将对象的内容拷贝到一个char
或者unsigned char
的数组中再使用memcpy
拷贝回来时,对象的内容保持不变。值得注意的是对于非POD类型来讲,C++没有这样的保证。固然,你可使用memcoy
在POD对象之间安全地拷贝。下面的例子中假设T是POD类型:#define N sizeof(T) char buf[N]; T obj; // obj initialized to its original value memcpy(buf, &obj, N); // between these two calls to memcpy, // obj might be modified memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type // holds its original value
f()
是不合法的,g()
是合法的。值得注意微软的编译器对于这条规则过于宽容--在全部例子中仅仅给出警告。int f() { struct NonPOD {NonPOD() {}}; goto label; NonPOD x; label: return 0; } int g() { struct POD {int i; char c;}; goto label; POD x; label: return 0; }
##结论 理解POD的确切含义是很重要的,由于正如你所看到的,许多语言特性对它们的行为是不一样的。this