POD的含义可以从两个显著的特性说明:
- 它支持静态初始化,而且
- 在C++中编译POD类型会和C中编译的struct类型得到相同的内存布局
正是因为这个,这个定义被划分为两个不同的概念:trivial 类型和standard-layout 类型,因为这比POD类型更有用。新标准中已经很少使用POD这个术语了,而是更多的在使用更精确的概念:trival和stand-layout。 POD
struct类型是既为trivial类型又为standard-layout类型,而且还没有非静态类型的non-POD struct和non-POD union(或者这些类型的数组)数据成员的non-union类型。
POD: 传统的C风格的struct,不能包含任何c++中的class的特性,比如构造函数、虚函数、继承、成员访问控制(只能是public),如果包含这些东西中的任意一个,就是non
POD。
POD。
trivial:
1.类里边有其他类变量(该类有缺省构造函数)2.类是从另外一个类继承而来(基类有缺省构造函数)3.类里边有虚函数。4.虚继承的情况。
standard layout: 如果满足这个特性,是指在C中struct和C++中的class有相同的内存布局。这个特性和trivial只有一点不同:
这里有一个规定放开了,那就是standard-layout类型的非静态数据成员必须是相同的访问控制,之前他们都必须是public类型的,但是现在他们可以是private或protected类型的了,只要他们都属于同一种。 当使用继承时,在整个继承体系中,只允许一个类拥有非静态数据成员,而且第一个非静态数据成员不能是基类的(这可能打乱量化规则),否则,就不是standard-layout类型。
- 没有 non-standard-layout类型(或这些类型的数组)和引用的非静态数据成员
-
没有虚函数和虚基类
- 非静态数据成员的访问控制必须是相同的
- 没有non-standard-layout的基类
-
在最底层的派生类中没有非静态数据成员,而且在最多有一个基类拥有非静态数据成员,或者没有拥有非静态数据成员
- 相同基类类型的非静态数据成员不能作为第一个成员
下面是trivial、standard layout和POD的一些比较代码:
#include <iostream>
#include <type_traits>
using namespace std;
class pod1 {}; //empty
class
class
class pod2 {public : int a;};//class
with public var
with public var
class pod3 {public : int b; pod2 p2;}; //class
with a obj
with a obj
class pod4 //class
with a static var
with a static var
{
public :
static int a;
int b;
};
class pod5 {int a;}; //class
with private var
with private var
class pod6 : public pod1 {}; //class
derived from a pod class
derived from a pod class
class pod7 : virtual public pod1 {};//class
virtual derived from a class
virtual derived from a class
class pod8 //class
with a user defined ctor, even if it's an empty function
with a user defined ctor, even if it's an empty function
{
pod8() {}
};
class pod9 //class
with a virtual fun
with a virtual fun
{
public :
virtual void test(){}
};
class pod10 //class
with non-static pod class
with non-static pod class
{
public :
pod2 &p;
};
class pod11 //class
with vars have different access type
with vars have different access type
{
public :
int a;
private :
int b;
};
class pod12 :public pod1
{
int a;
pod1 b;
};
class pod13 :public pod1 //first
member cannot be of the same type as base
member cannot be of the same type as base
{
pod1 b;
int a;
};
class pod14 : public pod2 {int b;};//
more than one class has non-static data members
more than one class has non-static data members
template <class T >
class test
{
public :
test()
{
cout<< typeid( T).name()<< "
" <<std::is_pod <T >::value<< "
"<<std:: is_trivial< T>::value<< "
" <<std::is_standard_layout <T >::value<<std::endl;
" <<std::is_pod <T >::value<< "
"<<std:: is_trivial< T>::value<< "
" <<std::is_standard_layout <T >::value<<std::endl;
}
};
int main()
{
test< pod1>();
test< pod2>();
test< pod3>();
test< pod4>();
test< pod5>();
test< pod6>();
test< pod7>();
test< pod8>();
test< pod9>();
test< pod10>();
test< pod11>();
test< pod12>();
test< pod13>();
test< pod14>();
}
结果: