c++11 pod類型(了解)


啥是POD類型?
POD全稱Plain Old Data。通俗的講,一個類或結構體通過二進制拷貝后還能保持其數據不變,那么它就是一個POD類型。

平凡的定義
1.有平凡的構造函數
2.有平凡的拷貝構造函數
3.有平凡的移動構造函數
4.有平凡的拷貝賦值運算符
5.有平凡的移動賦值運算符
6.有平凡的析構函數
7.不能包含虛函數
8.不能包含虛基類

[cpp] view plaincopy在CODE上查看代碼片派生到我的代碼片
#include "stdafx.h"  
#include <iostream>  
  
using namespace std;  
  
class A { A(){} };  
class B { B(B&){} };  
class C { C(C&&){} };  
class D { D operator=(D&){} };  
class E { E operator=(E&&){} };  
class F { ~F(){} };  
class G { virtual void foo() = 0; };  
class H : G {};  
class I {};  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    std::cout << std::is_trivial<A>::value << std::endl;  // 有不平凡的構造函數  
    std::cout << std::is_trivial<B>::value << std::endl;  // 有不平凡的拷貝構造函數  
    std::cout << std::is_trivial<C>::value << std::endl;  // 有不平凡的拷貝賦值運算符  
    std::cout << std::is_trivial<D>::value << std::endl;  // 有不平凡的拷貝賦值運算符  
    std::cout << std::is_trivial<E>::value << std::endl;  // 有不平凡的移動賦值運算符  
    std::cout << std::is_trivial<F>::value << std::endl;  // 有不平凡的析構函數  
    std::cout << std::is_trivial<G>::value << std::endl;  // 有虛函數  
    std::cout << std::is_trivial<H>::value << std::endl;  // 有虛基類  
  
    std::cout << std::is_trivial<I>::value << std::endl;  // 平凡的類  
  
    system("pause");  
    return 0;  
}  

運行結果



標准布局的定義
1.所有非靜態成員有相同的訪問權限
2.繼承樹中最多只能有一個類有非靜態數據成員
3.子類的第一個非靜態成員不可以是基類類型
4.沒有虛函數
5.沒有虛基類
6.所有非靜態成員都符合標准布局類型

[cpp] view plaincopy在CODE上查看代碼片派生到我的代碼片
#include "stdafx.h"  
#include <iostream>  
  
using namespace std;  
  
class A   
{   
private:  
    int a;  
public:  
    int b;  
};  
  
class B1  
{  
    static int x1;  
};  
  
class B2  
{  
    int x2;  
};  
  
class B : B1, B2  
{  
    int x;  
};  
  
class C1 {};  
class C : C1  
{  
    C1 c;  
};  
  
class D { virtual void foo() = 0; };  
class E : D {};  
class F { A x; };  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    std::cout << std::is_standard_layout<A>::value << std::endl;  // 違反定義1。成員a和b具有不同的訪問權限  
    std::cout << std::is_standard_layout<B>::value << std::endl;  // 違反定義2。繼承樹有兩個(含)以上的類有非靜態成員  
    std::cout << std::is_standard_layout<C>::value << std::endl;  // 違反定義3。第一個非靜態成員是基類類型  
    std::cout << std::is_standard_layout<D>::value << std::endl;  // 違反定義4。有虛函數  
    std::cout << std::is_standard_layout<E>::value << std::endl;  // 違反定義5。有虛基類  
    std::cout << std::is_standard_layout<F>::value << std::endl;  // 違反定義6。非靜態成員x不符合標准布局類型  
  
    system("pause");  
    return 0;  
}  

運行結果



POD的使用
當一個數據類型滿足了”平凡的定義“和”標准布局“,我們則認為它是一個POD數據。可以通過std::is_pod來判斷一個類型是否為POD類型。
如文章開頭說的,一個POD類型是可以進行二進制拷貝的,看看下面的例子。

[cpp] view plaincopy在CODE上查看代碼片派生到我的代碼片
#include "stdafx.h"  
#include <iostream>  
#include <Windows.h>  
  
using namespace std;  
  
class A   
{   
public:  
    int x;  
    double y;  
};  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    if (std::is_pod<A>::value)  
    {  
        std::cout << "before" << std::endl;  
        A a;  
        a.x = 8;  
        a.y = 10.5;  
        std::cout << a.x << std::endl;  
        std::cout << a.y << std::endl;  
  
        size_t size = sizeof(a);  
        char *p = new char[size];  
        memcpy(p, &a, size);  
        A *pA = (A*)p;  
  
        std::cout << "after" << std::endl;  
        std::cout << pA->x << std::endl;  
        std::cout << pA->y << std::endl;  
  
        delete p;  
    }  
  
    system("pause");  
    return 0;  
}  

運行結果



可以看到,對一個POD類型進行二進制拷貝后,數據都成功的遷移過來了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM