trivial、standard layout和POD的比较

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

结果:
trivial、standard layout和POD的比较_第1张图片

你可能感兴趣的:(C++,STL)