多重継承のメモリレイアウトが定義されていないことを知っているので、それに依存するべきではありません。ただし、特別な場合にそれを信頼できますか。つまり、クラスには「実際の」スーパークラスが1つだけあります。他のすべては「空のクラス」です。つまり、フィールドも仮想メソッドも持たないクラスです(つまり、非仮想メソッドしかありません)。この場合、これらの追加クラスは、クラスのメモリレイアウトに何も追加しないでください。(より簡潔に言えば、C ++ 11の表現では、クラスには標準レイアウトがあります)
すべてのスーパークラスにオフセットがないと推測できますか?例えば:
#include <iostream>
class X{
int a;
int b;
};
class I{};
class J{};
class Y : public I, public X, public J{};
int main(){
Y* y = new Y();
X* x = y;
I* i = y;
J* j = y;
std::cout << sizeof(Y) << std::endl
<< y << std::endl
<< x << std::endl
<< i << std::endl
<< j << std::endl;
}
Y
これがX
、唯一の実際の基本クラスであるクラスです。プログラムの出力(g ++ 4.6を使用してLinuxでコンパイルした場合)は次のとおりです。
8
0x233f010
0x233f010
0x233f010
0x233f010
結論として、ポインタの調整はありません。しかし、この実装は特定のものですか、それとも信頼できますか。つまり、タイプのオブジェクトを受け取った場合I
(そして、これらのクラスのみが存在することがわかっている場合)、を使用してオブジェクトreinterpret_cast
をキャストできX
ますか?
オブジェクトのサイズは少なくとも1バイトでなければならないと仕様に記載されているので、私はそれを信頼できることを望んでいます。したがって、コンパイラは別のレイアウトを選択できません。I
のメンバーのJ
後ろにレイアウトする場合X
、サイズはゼロになります(メンバーがないため)。したがって、唯一の合理的な選択は、オフセットなしですべてのスーパークラスを整列させることです。
I
ここからreinterpret_castを使用した場合、私は正しいですか、それとも火遊びをしてX
いますか?