啥是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類型進行二進制拷貝后,數據都成功的遷移過來了。