日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 11 中的POD

發布時間:2025/4/9 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 11 中的POD 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

POD 是英文中Plain Old Data 的縮寫,意如其名。 Plain 表示了POD 是普通的類型, C++中常見的類型都是這樣的屬性,而不像一些存在著虛函數虛繼承的類型那么特別。 Old 則體現其和C 的兼容性。 比如可以用古老的memcpy() 函數進行復制, 使用memset()進行初始化等。

使用POD 有以下幾個好處:

1. 字節賦值, 可以安全地使用memset 和memcpy對POD 進行初始化和拷貝等操作。

2. 提供對C內存布局兼容,C++ 程序可以與C函數進行相互操作,因為POD 的類型的數據在C和C++間操作總是安全的

3. 保證了靜態初始化的安全有效。 靜態初始化在很多時候能夠提升程序的性能,而POD 類型的對象初始化往往簡單(比如放在目標文件的.bss 段,在初始化中直接賦0)。

在C++ 11 中,對POD 劃分為兩個概念的集合, 即: 平凡的(Trivial) 和標準布局的。

  通常情況下, 一個平凡的類或結構體應該符合以下定義

  • 擁有平凡的默認構造函數(Trivial constructor)和析構函數(trivial destructor)
  •     平凡的默認構造函數就是說構造函數什么都不干, 通常情況下, 不定義類的構造函數,編譯器會為我們生產一個平凡的默認構造函數,而一旦定義了構造函數,即使構造函數不包含參數,函數提里面沒有任何代碼,那么該構造函數也就不再是 ‘平凡的‘。 比如:

    struct NonTrivial {Nontrivial() {} };

    ?  也可以使用=default關鍵字顯式申明缺省的版本的構造函數,使其’平凡化‘。

      2. 擁有平凡?的拷貝構造函數(trivial copy constructor)和移動構造函數(trivial move constructor). 平凡的拷貝構造函數基本上等同于使用memcpy進行類型的構造。同樣地,也可使用=default申明默認的拷貝構造函數。平凡的移動構造函數和平凡的拷貝構造函數類似,只不是用于移動語義。

    ?

      3. 擁有平凡的拷貝賦值運算符(trivial assignment operator) 和移動賦值運算符(Trivial move operator),基本上與平凡的拷貝構造函數和平凡的移動構造函數運算符類似。

      4. 不能包含虛函數和虛繼承

    在C++ 11 中,可以使用輔助類模版類判斷一個類或結構體是不是平凡的

    template <typename T> struct std::is_trivial;

    類is_trivial 的成員value 可以用于判斷類型T 是不是平凡的類型。下面的代碼總結了這四種情況:

    #include <iostream> #include <type_traits>using namespace std;struct Trivial1 { }; struct Trivial2 { public: int a; private:int b; };struct Trivial3{Trivial1 a;Trivial2 b; };struct Trivial4{Trivial2 a[20]; };struct Trivial5{int x;static int y; };struct NonTrivial1{NonTrivial1() : z(42){}int z; };struct NonTrivial2{NonTrivial2(){}int w;};struct NonTrivial3 {Trivial5 c;virtual void f(){} };int main(int argc, char* argv[]) {cout << is_trivial<Trivial1>::value << endl; //1cout << is_trivial<Trivial2>::value << endl; //1cout << is_trivial<Trivial3>::value << endl; //1cout << is_trivial<Trivial4>::value << endl; //1cout << is_trivial<Trivial5>::value << endl; //1cout << is_trivial<NonTrivial1>::value << endl; //0cout << is_trivial<NonTrivial2>::value << endl; //0cout << is_trivial<NonTrivial3>::value << endl; //0return 0; }

    ?POD 包含的另外一個概念是標準布局, 標準布局的類或結構體應該符合以下的定義:

      1. 所有非靜態成員有相同的訪問權限(Public, protected, private)

      2. 在類或結構體繼承時,滿足一下兩種情況之一

        a. 派生類中有非靜態成員,且只有一個僅包含靜態成員的基類

        b. 基類有非靜態成員,而派生類沒有非靜態成員

      這樣的類或結構體是標準布局的,比如下面的例子:

      

    struct B1 { static int a; } ; struct D1 : B1 { int d; };struct B2 { int a; }; struct D2 : B2 { static int d; };struct D3 : B2, B1 { static int d; }; struct D4 : B2 { int d; }; struct D5: B2, D1 { };

    ?  D1, D2, D3都是標準布局的, D4,D5則不屬于標準布局,這實際上使得非靜態成員只要同時出現在基類或者派生類中, 其即屬于非標準布局,而多重繼承也會導致類型布局的一些變化,所以一旦非靜態成員出現在多個基類中,派生類也不屬于標準布局

      3. 類中的第一個非靜態成員的類型與其基類相同

      

    struct A : B { B b; };

    ?  這樣的情況A 就不是一個標準布局,而如下例子:

    struct A:B {int a; B b; };

    ?則是一個標準布局

      

      4. 沒有虛函數和虛繼承

      5. 所有非靜態數據成員均符合標準布局類型,其基類也符合標準布局。

    同樣,在C++11 中,可以使用模版類is_standard_layout 來判斷一個類是不是標準布局的

    template <typename T> struct std::is_standard_layout

    通過is_standard_layout 模版類的成員 value, 可以判斷出其實不是標準布局。

    #include <iostream> #include <type_traits> using namespace std; struct SLayout1 {}; struct SLayout2 { private:int a;int b; };struct SLayout3 : SLayout1 {int a;int b;void f(){} };struct SLayout4 : SLayout1 {int a;SLayout1 b; };struct SLayout5 : SLayout1, SLayout3 { };struct SLayout6 { static int a; };struct SLayout7 :SLayout6 { int a; };struct NonSLayout1 : SLayout1{ SLayout1 a; int i; }; struct NonSLayout2 : SLayout2{ int c; }; struct NonSLayout3 : NonSLayout2 {}; struct NonSLayout4 { public: int a; private:int b; };int main(int argc, char* argv[]) {cout << "Is Standard layout:" << endl;cout << is_standard_layout<SLayout1>::value << endl; //1cout << is_standard_layout<SLayout2>::value << endl; //1cout << is_standard_layout<SLayout3>::value << endl; //1cout << is_standard_layout<SLayout4>::value << endl; //1cout << is_standard_layout<SLayout5>::value << endl; //1cout << is_standard_layout<SLayout6>::value << endl; //1cout << is_standard_layout<SLayout7>::value << endl; //1cout << is_standard_layout<NonSLayout1>::value << endl; //0cout << is_standard_layout<NonSLayout2>::value << endl; //0cout << is_standard_layout<NonSLayout3>::value << endl; //0return 0; }

    ? 同樣,要判斷一個類型是不是POD, 標準庫中的<type_traits> 頭文件提供了如下模版類:

    template<typename T> struct std::is_pod;

    可以使用std::is_pod<T>::value 來判斷一個類型是不是POD。

    轉載于:https://www.cnblogs.com/zhouminliang/p/3357073.html

    總結

    以上是生活随笔為你收集整理的C++ 11 中的POD的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。