8

C 構造体では、次のことが保証されています。

struct Foo { ... };
struct Bar {
  Foo foo;
  ...
}
Bar bar;
assert(&bar == &(bar.foo));

さて、C ++で、私が持っている場合:

class Foo { ... };
class Bar: public Foo, public Other crap ... {
  ...
}

Bar bar;
assert(&bar == (Foo*) (&bar)); // is this guaranteed?

もしそうなら、参考文献を教えてもらえますか (「C++ プログラミング言語、ページ xyz」など)。

ありがとう!

4

3 に答える 3

10

保証はありません。C++03 標準 (10/3、class.built) から:

最も派生したオブジェクト (1.8) で基本クラスのサブオブジェクトが割り当てられる順序は指定されていません。

于 2010-01-31T06:28:14.960 に答える
6

基本クラスのレイアウトは、あなたが考えているように保証されていませんが (メンバーにはより多くの保証がありますが)、これは保証されています:

Bar bar;
assert(&bar == (Foo*) (&bar));

キャストは正しく変換される static_cast (5.4 あたり) を使用&barし、ポインターからベースへのポインターと派生ポインターへの比較は同様に変換されるためです。

ただし、これは保証されません。

Bar bar;
void* p1 = &bar;
void* p2 = (Foo*)&bar;
assert(p1 == p2); // not guaranteed
于 2010-01-31T06:37:33.977 に答える
1

そうなるとは思いませんが、なぜそうしなければならないのかわかりません。

関連する質問があります。

ダイヤモンドの継承がある場合:

class Base(){ virtual void AFunc(){}  };

class A:Base{};
class B:Base{void AFunc(){} }

class Test:A,B{};


Base * b = (Base*)new Test;

b->AFunc();

メモリ構造が Base:A:B:Test であると仮定します。

呼び出しの時点で、コンパイラが知っているのはオブジェクトの先頭のアドレスだけであり、AFunc は B オブジェクトの先頭からの相対アドレスであると想定しているため、これら 2 つのアドレスは同じではありません! それで、それはどのように機能しますか?

b がタイプ B の場合のように、2 つのアドレスは同じになります...

于 2010-01-31T06:33:09.100 に答える