pod(程式語言)

Plain old data structure,縮寫為POD,是C++語言的標準中定義的一類數據結構,POD適用於需要明確的數據底層操作的系統中。POD通常被用在系統的邊界處,即指不同系統之間只能以底層數據的形式進行互動,系統的高層邏輯不能互相兼容。比如當對象的欄位值是從外部數據中構建時,系統還沒有辦法對對象進行語義檢查和解釋,這時就適用POD來存儲數據。

基本介紹

  • 中文名:POD
  • 外文名:Plain old data structure
  • 縮寫:POD
  • 領域:程式語言
  • 釋義:一類數據結構
定義,標量類型,POD類類型,C++11,用途,POD JAVA,參見,

定義

POD類型包括下述C++類型,以及其cv-qualified的類型,還有以其為基類型的數組類型:
  • 標量類型(scalar type) ;
  • POD類類型(POD class type)。

標量類型

術語標量類型包括下述C++類型範疇, 以及其cv-qualified類型:
  • 算術類型(arithmetic type);
  • 枚舉類型(enumeration type);
  • 指針類型(pointer type);
  • 指針到成員類型(pointer-to-member type)。
術語算術類型包括下述C++類型範疇:
  • 整數類型(integral type);
  • 浮點類型(floating type)。
術語整數類型包括下述C++類型範疇:
  • 有符號整數類型 (signed char, short, int, long);
  • 無符號整數類型(unsigned char, unsigned short, unsigned int, unsigned long);
  • 字元類型char與寬字元類型wchar_t;
  • 布爾類型bool。
術語浮點類型包括C++的float, double, and long double類型。
術語枚舉類型包括各種枚舉類型,即命名的常量值(named constant values)的集合。
術語指針類型包括下述C++類型範疇:
  • 空指針pointer-to-void (void *);
  • 對象指針pointer-to-object與指向靜態數據成員的指針pointer-to-static-member-data (都是形如為T*,其中T是對象類型);
  • 函式指針pointer-to-function與指向靜態成員函式的指針pointer-to-static-member-function (都是形如T (*)(...),T是函式的返回值的類型)。

POD類類型

POD類類型是指聚合類(aggregate classes, 即POD-struct types)與聚合union (POD-union types),且不具有下述成員:
  • 指針到成員類型的非靜態數據成員(包括數組)。
  • 非POD類類型的非靜態數據成員(包括數組)。
  • 引用類型的(reference type)非靜態數據成員。
  • 用戶定義的拷貝與賦值運算元。
  • 用戶定義的析構函式。
術語聚合是指任何的數組或者類,且不具有下述特徵:
  • 用戶定義的構造函式。
  • 私有或保護的非靜態數據成員。
  • 基類。
可見,POD類類型就是指class、struct、union,且不具有用戶定義的構造函式、析構函式、拷貝運算元、賦值運算元;不具有繼承關係,因此沒有基類;不具有虛函式,所以就沒有虛表;非靜態數據成員沒有私有或保護屬性的、沒有引用類型的、沒有非POD類類型的(即嵌套類都必須是POD)、沒有指針到成員類型的(因為這個類型內含了this指針)。

C++11

C++11把情況推廣為兩種:
類型是平凡的(trivial),則可以靜態初始化、可以用memcpy直接複製數據而不是必須用copy構造函式。其生存期始於它的對象的存儲被定義,無須等到構造函式完成。平凡class或結構必須滿足:
  • 有平凡的預設構造函式,可用這樣的默認語法:(SomeConstructor() = default;)
  • 有平凡的copy與move構造函式,可用默認語法.
  • 有平凡的copy與move運算符,可用默認語法.
  • 有平凡的destructor,不能是虛函式.
構造函式是平凡的,僅當類沒有虛成員函式也沒有虛基類。Copy/move運算符是平凡的,僅當沒有靜態數據成員。
類型是標準布局的(standard-layout)意味著它是有序的並且安排其成員兼容於C語言。這要求滿足:
  • 沒有虛函式
  • 沒有虛基類
  • 所有非靜態數據成員有相同的訪問控制(public, private, protected)
  • 所有非靜態數據成員,包括在任何基類中的,存在於類繼承體系中的一個類中
  • 上述規則適用於所有基類與類繼承體系中的所有非靜態數據成員
  • 沒有同一類型的基類型被定義為第一個非靜態數據成員
一個class/struct/union是POD,當它是平凡的、標準布局的,所有數據成員是POD.
分為兩個概念,對象可以不滿足其中一個但是滿足另外一個。例如,類有複雜的move與copy構造函式,因此不是平凡的,但可能是標準布局因此能與C程式互操作。類似地,一個類的有public與private的非靜態數據成員,因此不是標準布局,但可以是平凡的因此可以memcpy操作。

用途

POD類型在原始碼兼容於ANSI C時非常重要。POD對象與C語言的對應對象具有共同的一些特性,包括初始化、複製、記憶體布局、定址。
一個例子是下述C++的new表達式中的對象初始化,POD與non-POD的區別:
表達式POD類型Tnon-POD類型T
new T
不初始化
預設初始化
new T()
總是預設初始化
new T(x)
總是調用構造函式初始化
因此,non-POD類型的對象或數組總是被初始化;而POD類型的對象或數組可能未被初始化.
其它與POD相關的C++特性:
  • 記憶體布局——POD對象的組成位元組是連續的。
"POD-struct ... types are layout-compatible if they have the same number of members, and corresponding members (in order) have layout-compatible types".
POD-union ... types are layout-compatible if they have the same number of members, and corresponding members (in any order) have layout-compatible types".
  • 初始化——對於non-const POD對象,如果沒有初始化聲明時,具有不確定的初值(indeterminate initial value). POD對象的預設初始化為0值. 靜態POD對象初始化為給定的初值,如果是局部靜態POD對象,在進入所在作用域之前初始化[§6.7, ¶4]; 對於非局部靜態POD對象,在任何動態初始化之前賦予初值.
  • 拷貝——POD對象可直接拷貝(例如用memcpy())到其它字元數組或相同POD類型的對象,保持其值不變。POD類型可以用作標準模板字元串類的字元. 由於這個原因,函式的返回值如果是non-POD類型,則不能通過暫存器傳遞函式的返回值。
  • 定址——一個POD對象的地址可以是一個地址常量表達式;一個對POD成員的引用可以是一個引用常量表達式。 一個POD-struct對象的指針,適合用reinterpret_cast轉換到它的初始值。

POD JAVA

JAVA中,一些開發者認為POD類型是匹配沒有public成員且沒有方法的類,比如data transfer object。其實不使用事件句柄並且不實現除getter和setter之外的附加方法的POJO(只含有getter和setter的類)和JAVA Bean也屬於POD。但不管怎么樣,POJO和JAVA Bean已經有了封裝,已經違反了POD的定義了。

參見

Visual C++名字修飾

相關詞條

熱門詞條

聯絡我們