您的位置:首页 > 编程语言 > C语言/C++

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

2014-04-10 10:57 417 查看
POD types

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;




};





這裏有個幾個例子能讓你彻底明白每個trivial類型:



点击(此处)折叠或打开






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;


原文:

















阅读(386) | 评论(0) | 转发(1) |



0
上一篇:编译错误:stray ‘\357’ in program的解决方法

下一篇:求职简历撰写要点和模板分享




相关热门文章

test123

编写安全代码——小心有符号数...

使用openssl api进行加密解密...

一段自己打印自己的c程序...

sql relay的c++接口



我的ChinaUnix博客被锁定了,...

虚拟机中ubuntu无线连接问题...

IBM DS3400 盘阵怎么查看是单...

启动auditd时,报错如下,怎么...

CGSL系统中root密码正确,但无...








给主人留下些什么吧!~~






评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: