C++0xではPODでもコンストラクタ相当のことができる・・・? - Faith and Brave - C++で遊ぼう
それは、本当にPODであることが必要なのだろうか。C++0xでは、PODを細分化した。なぜ、プログラマーはPODを使いたがるのか。それは結局、二つの理由がある。
- 構造体のオブジェクトを単なるバイト列にコピーして、差し戻したい
- 構造体へのポインターは、構造体の最初のメンバーの指し示して欲しい
いわば、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:
Post a Comment