C++中的Trivial 、POD、non-POD和Standard Layout概念
POD types
non-POD types
Standard Layout types
更多请参考:
這裏有個幾個例子能讓你彻底明白每個trivial類型:
這裏有個幾個例子能讓你彻底明白每個standard-layout類型:
結論:
原文:
阅读(386) | 评论(0) | 转发(1) |
non-POD types
Standard Layout types
A Formal Definition
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的析构函数
更多请参考:
struct N { // neither trivial nor standard-layout
int i;
int j;
virtual ~N();
};
// 有一个虚拟函数就不是trivial和standard-layout
struct T { // trivial but not standard-layout
int i;
private:
int j;
};
// 数据成员访问类型不同就不是standard-layout,但可以是trivial
struct SL { // standard-layout but not trivial
int i;
int j;
~SL();
};
// 有非虚拟的析构或非默认的构造函数,就不是trivial,但可以是standard-layout
struct POD { // both trivial and standard-layout
int i;
int j;
};
int i;
int j;
virtual ~N();
};
// 有一个虚拟函数就不是trivial和standard-layout
struct T { // trivial but not standard-layout
int i;
private:
int j;
};
// 数据成员访问类型不同就不是standard-layout,但可以是trivial
struct SL { // standard-layout but not trivial
int i;
int j;
~SL();
};
// 有非虚拟的析构或非默认的构造函数,就不是trivial,但可以是standard-layout
struct POD { // both trivial and standard-layout
int i;
int j;
};
点击(此处)折叠或打开
-
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 };
這裏有個幾個例子能讓你彻底明白每個standard-layout類型:
点击(此处)折叠或打开
-
1 // empty classes have standard-layout
-
2 struct StandardLayout1 {};
-
3
-
4 struct StandardLayout2 {
-
5 int x;
-
6 };
-
7
-
8 struct StandardLayout3 {
-
9 private: // both are private, so it's ok
-
10 int x;
-
11 int y;
-
12 };
-
13
-
14 struct StandardLayout4 : StandardLayout1 {
-
15 int x;
-
16 int y;
-
17
-
18 void f(); // perfectly fine to have non-virtual functions
-
19 };
-
20
-
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
-
35 };
-
36
-
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 {
-
46 int x;
-
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 };
-
57
-
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)在頭文件<type_traits>中定義了對這些類型的檢測:
1 template <typename T> 2 struct std::is_pod; 3 template <typename T> 4 struct std::is_trivial; 5 template <typename T> 6 struct std::is_trivially_copyable; 7 template <typename T> 8 struct std::is_standard_layout;
原文:
相关热门文章
给主人留下些什么吧!~~
评论热议