天天看点

C++中的Trivial 、POD、non-POD和Standard Layout概念

POD types

non-POD types

Standard Layout types

Informally, a standard layout class is one without direct or indirect virtual member functions, reference data members or virtual base classes. Formally, a standard-layout class is a class that:

Has no non-static data members of type non-standard-layout class (or array of such types) or reference. In simpler words, a standard layout class shall not have reference variables as data members or member objects of a non-standard layout class.

Has no virtual functions and no virtual base classes.

Has the same access control for all non-static data members.

Has no non-standard-layout base classes.

Either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members.

Has no base classes of the same type as the first non-static data member.

standard-layout 类型的类是指:

没有 non-standard-layout类型(或这些类型的数组)和引用的非静态数据成员

没有虚函数和虚基类

非静态数据成员的访问控制必须是相同的

没有non-standard-layout的基类

在最底层的派生类中没有非静态数据成员,而且在最多有一个基类拥有非静态数据成员,或者没有拥有非静态数据成员

相同基类类型的非静态数据成员不能作为第一个成员

C++标准把trivial类型定义如下:

一个拷贝不变(trivially copyable)类型是指:

没有non-trivial 的复制构造函数

没有non-trivial的转移构造函数

没有non-trivial的赋值操作符

没有non-trivial的转移赋值操作符

有一个trivial的析构函数

C++中的Trivial 、POD、non-POD和Standard Layout概念

<a href="http://www.cnblogs.com/tingshuo/archive/2013/03/28/2986236.html" target="_blank"></a>

<a href="http://www.cnblogs.com/tingshuo/archive/2013/03/28/2986236.html" target="_blank">点击(此处)折叠或打开</a>

<a href="http://www.cnblogs.com/tingshuo/archive/2013/03/28/2986236.html" target="_blank">這裏有個幾個例子能讓你彻底明白每個trivial類型:</a>

点击(此处)折叠或打开

1 // empty classes are trivial

 2 struct Trivial1 {};

 3

 4 // all special members are implicit

 5 struct Trivial2 {

 6 int x;

 7 };

 8

 9 struct Trivial3 : Trivial2 { // base class is trivial

10 Trivial3() = default; // not a user-provided ctor

11 int y;

12 };

13

14 struct Trivial4 {

15 public:

16 int a;

17 private: // no restrictions on access modifiers

18 int b;

19 };

20

21 struct Trivial5 {

22 Trivial1 a;

23 Trivial2 b;

24 Trivial3 c;

25 Trivial4 d;

26 };

27

28 struct Trivial6 {

29 Trivial2 a[23];

30 };

31

32 struct Trivial7 {

33 Trivial6 c;

34 void f(); // it's okay to have non-virtual functions

35 };

36

37 struct Trivial8 {

38 int x;

39 static NonTrivial1 y; // no restrictions on static members

40 }

41

42 struct Trivial9 {

43 Trivial9() = default; // not user-provided

44 // a regular constructor is okay because we still have default ctor

45 Trivial9(int x) : x(x) {};

46 int x;

47 }

48

49 struct NonTrivial1 : Trivial 3 {

50 virtual f(); // virtual members make non-trivial ctors

51 }

52

53 struct NonTrivial2 {

54 NonTrivial2() : z(42) {} // user-provided ctor

55 int z;

56 }

57

58 struct NonTrivial3 {

59 NonTrivial3(); // user-provided ctor

60 int w;

61 }

62 NonTrivial3::NonTrivial3() = default; // defaulted but not on first declaration

63 // still counts as user-provided

64 struct NonTrivial5 {

65 virtual ~NonTrivial5(); // virtual destructors are not trivial

66 };

<a href="http://www.cnblogs.com/tingshuo/archive/2013/03/28/2986236.html" target="_blank">這裏有個幾個例子能讓你彻底明白每個standard-layout類型:</a>

1 // empty classes have standard-layout

 2 struct StandardLayout1 {};

 4 struct StandardLayout2 {

 5 int x;

 6 };

 7

 8 struct StandardLayout3 {

 9 private: // both are private, so it's ok

10 int x;

14 struct StandardLayout4 : StandardLayout1 {

15 int x;

16 int y;

17

18 void f(); // perfectly fine to have non-virtual functions

21 struct StandardLayout5 : StandardLayout1 {

22 int x;

23 StandardLayout1 y; // can have members of base type if they're not the first

24 };

25

26 struct StandardLayout6 : StandardLayout1, StandardLayout5 {

27 // can use multiple inheritance as long only

28 // one class in the hierarchy has non-static data members

29 };

30

31 struct StandardLayout7 {

32 int x;

33 int y;

34 StandardLayout7(int x, int y) : x(x), y(y) {} // user-provided ctors are ok

37 struct StandardLayout8 {

38 public:

39 StandardLayout8(int x) : x(x) {} // user-provided ctors are ok

40 // ok to have non-static data members and other members with different access

41 private:

42 int x;

43 };

44

45 struct StandardLayout9 {

47 static NonStandardLayout1 y; // no restrictions on static members

48 };

49

50 struct NonStandardLayout1 {

51 virtual f(); // cannot have virtual functions

52 };

53

54 struct NonStandardLayout2 {

55 NonStandardLayout1 X; // has non-standard-layout member

56 };

58 struct NonStandardLayout3 : StandardLayout1 {

59 StandardLayout1 x; // first member cannot be of the same type as base

60 };

61

62 struct NonStandardLayout4 : StandardLayout3 {

63 int z; // more than one class has non-static data members

64 };

65

66 struct NonStandardLayout5 : NonStandardLayout3 {}; // has a non-standard-layout base class

結論:

在新的標准下,很多新類型成为POD類型,而且,就算一個類型不是POD類型,我們也可以分別利用POD類型的特性(只要這個類型是trivial或者standard-layout)。

標准模板塊(STL)在頭文件中定義了對這些類型的檢測:

原文:

C++中的Trivial 、POD、non-POD和Standard Layout概念

继续阅读