this
objectのアドレスを提供しますが、これは必ずしも最初のメンバーのアドレスではありません。唯一の例外は、いわゆる標準レイアウトタイプです。C++11 標準から:
(9.2/20) を使用して適切に変換された標準レイアウト構造体オブジェクトへのポインターは、reinterpret_cast
その最初のメンバー (または、そのメンバーがビットフィールドの場合は、それが存在するユニット) を指し、その逆も同様です。[ 注: したがって、標準レイアウトの構造体オブジェクト内に名前のないパディングがある場合がありますが、適切な配置を実現するために必要な場合は、先頭にはありません。— エンドノート]
これは、標準レイアウト タイプの定義です。
(9/7) 標準レイアウト クラスとは、次のようなクラスです。
— 非標準レイアウト クラス (またはそのような型の配列) または参照の非静的データ メンバーを
持たない — 仮想関数 (10.3) を持たず、仮想基底クラスがない (10.1)
— すべての非静的データ メンバーに対して同じアクセス制御 (条項 11) がある
— 非標準レイアウトの基底クラス
がない — ほとんどの派生に非静的データ メンバーがないクラスと、非静的データ メンバーを持つ最大 1 つの基本クラス、または非静的データ メンバーを
持つ基本クラスがなく、かつ — 最初の非静的データ メンバーと同じ型の基本クラスがない。[108]
[108]これにより、同じクラス型を持ち、同じ最派生オブジェクトに属する 2 つのサブオブジェクトが同じアドレス (5.10) に割り当てられないことが保証されます。
オブジェクト タイプが POD である必要はないことに注意してください。上記で定義した標準レイアウトで十分です。(POD はすべて標準レイアウトですが、さらに、簡単に構築可能で、簡単に移動でき、簡単にコピーできます。)
あなたのコードからわかる限り、あなたのタイプは標準レイアウトのようです (アクセス制御がすべての非静的データ メンバーに対して同じであることを確認してください)。この場合、this
実際に最初のメンバーを指します。シリアライゼーションの目的でこれを使用することに関して、標準では実際に明示的に次のように述べています。
(9/9) [ 注: 標準レイアウト クラスは、他のプログラミング言語で記述されたコードとの通信に役立ちます。それらのレイアウトは 9.2 で指定されています。— エンドノート]
もちろん、これでシリアル化の問題がすべて解決するわけではありません。特に、シリアル化されたデータの移植性は得られません (たとえば、エンディアンの非互換性のため)。