现在的位置: 首页 > 综合 > 正文

trivial、standard layout和POD的比较

2018年02月23日 ⁄ 综合 ⁄ 共 2515字 ⁄ 字号 评论关闭

POD的含义可以从两个显著的特性说明:

  1. 它支持静态初始化,而且
  2. 在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。
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 pod2 {public int a;};//class
with public var
class pod3 {public int b; pod2 p2;};      //class
with a obj
class pod4      //class
with a static var
{
public :
        static int a;
        int b;
};
class pod5 {int a;};   //class
with private var
class pod6 public pod1 {}; //class
derived from a pod class
class pod7 virtual public pod1 {};//class
virtual derived from a class
class pod8      //class
with a user defined ctor, even if it's an empty function
{
       pod8() {}
};
class pod9      //class
with a virtual fun
{
public :
        virtual void test(){}
};

class pod10     //class
with non-static pod class
{
public :
        pod2 &p;
};
class pod11     //class
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
{
        pod1 b;
        int a;
};
class pod14 public pod2 {int b;};//
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;
       }
};

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>();
}

结果:

抱歉!评论已关闭.