2010-05-13

PODじゃなくてもいいのでは。

C++0xではPODでもコンストラクタ相当のことができる・・・? - Faith and Brave - C++で遊ぼう

それは、本当にPODであることが必要なのだろうか。C++0xでは、PODを細分化した。なぜ、プログラマーはPODを使いたがるのか。それは結局、二つの理由がある。

  1. 構造体のオブジェクトを単なるバイト列にコピーして、差し戻したい
  2. 構造体へのポインターは、構造体の最初のメンバーの指し示して欲しい

いわば、Cとの互換性や、その他の言語との相互利用のために、PODを利用するのだ。

struct POD
{
    int x ;
    int y ;
} ;

int main()
{
    POD pod = { 1, 1 };
    char a[sizeof(POD)] ;
    std::memcpy( a, &pod, sizeof(POD) ) ;// 単なるバイト列へコピー

    pod.x = 2 ;
    std::memcpy( &pod, a, sizeof(POD) ) ;// 差し戻す
    
    // ここで、pod.x == 1   

    // オブジェクトへのポインターをキャスト
    int * p1 = reinterpret_cast<int *>( &pod ) ;
    int * p2 = &pod.x ;

    // ここで、p1 == p2
}

しかし、このようなことは、PODではなくても、保証できるのではないか。そこで、C++0xでは、PODの機能を細分化した。どうすれば、trivially copyable classやstandard-layout classになるのかという条件は、省略する。規格を参照して欲しい。

trivially copyable class

このクラスは、triviallyにコピーができることを保証するものである。つまり、charやunsigned charの配列にmemcpyして、差し戻した場合、オブジェクトのストレージは、全く同じ状態になることが保証される。

standard-layout class

このクラスは、オブジェクトへのポインターは、クラスの最初のデータメンバーを指し示すことを保証するものである。つまり、reinterpret_castを使って、オブジェクトへのポインターを、最初のデータメンバーのポインターにキャストした場合、ポインターは、最初のデータメンバーを指すことが保証される。

では、PODとは何か。まず、trivial classというものが定義されている。これは、trivially copyable classで、さらに、ユーザー定義のデフォルトコンストラクターがないものである。PODとは、trivial classかつ、standard-layout classである。

つまり、これまでのPODの本質的な機能は、trivially copyable classと、standard-layout classで実現できる。PODである必要はない。C++0xは、PODが、実質、trivially copyable classと、standard-layout classを実現するために使われているという現状を鑑みて、PODでなくても、そのような保証ができるようにした。第一、デフォルトコンストラクターの有無は、クラスのレイアウトには、影響しないのだから。

まだPODであることを必要とするのだろうか。

No comments: