C++ POD類型
背景
POD(Plain Old Data)指的是C++定義的和C相兼容的數據結構。
幾乎所有的系統底層都是用C寫的,當時定義的基本數據類型比如int、char、float、枚舉、指針、數組和結構等通過二進制拷貝後還能保持數據不變,即編譯器可以通過二進制數據將該類型正確解析出來。C++中的類類型引入了繼承和派生等新概念,編譯器無法解析這些複雜數據結構,因此C++提出POD數據結構的概念用於兼容C語言,由於C++中基本內置類型都是POD類型,因此我們一般討論class
、struct
和union
是否是POD類型的。
POD類型的優勢
1. C內存佈局兼容
POD類型兼容C內存佈局,C++可以直接使用C庫函數操作POD數據類型,POD類型在C和C++間的操作總是安全的。
2. 可以使用字節賦值
POD類型可以直接使用字節賦值,使用C語言庫函數進行二進制形式的數據交換,包括但不限於如下操作:
malloc
創建memset
設置內存memcpy
和memmove
拷貝內存
3. 保證靜態初始化的安全有效
靜態初始化在很多時候可以提高程序性能,而POD類型的靜態初始化非常簡單(放入目標文件的.bss
段,在初始化時直接賦0)
4. 其他特性
雖然與C完全兼容,但是仍然可以有成員函數
有更長的生命週期(從資源獲取到資源釋放),非POD類型的生命週期從構造函數結束到析構函數結束
POD類型對象的前部沒有填充字節,因此對象指針等於對象第一個成員的指針
POD類型判斷
在C++中,可以通過
is_pod<T>::value
來判斷某個類型是否是POD類型。
POD類型的具體要求如下(這裏只討論類類型,即class
、struct
和union
):
1. trival
一個類類型是trival
的需要滿足如下條件:
默認指的是編譯器自動生成的版本,用戶定義的拷貝控制操作即使函數體爲空也不算
trival
的,C++11以後可以使用=default
顯式使用編譯器自動生成的版本。
默認的構造函數與析構函數
默認的拷貝構造函數和移動構造函數
默認的拷貝賦值運算符和移動賦值運算符
不能包含虛函數和虛基類
2. 標準佈局
所有非靜態數據均爲標準佈局類型
所有基類均爲標準佈局類型
所有非靜態成員具有相同的訪問權限
沒有虛函數
沒有虛基類
類中的第一個非靜態成員與其任何基類的類型不同
要麼所有基類都沒有非靜態成員,要麼最下層的子類沒有非靜態成員且最多隻有基類有非靜態數據成員(總之繼承樹中最多隻能有一個類有非靜態數據成員)
Reference
[1] https://zhuanlan.zhihu.com/p/45545035
[2] https://blog.csdn.net/kongkongkkk/article/details/77414410
[3] https://www.cnblogs.com/jerry-fuyi/archive/2020/05/09/12854248.html