13

「EffectiveC++」(第3版、118ページ)の項目27で、ScottMeyersは次のように述べています。

class Base { ... };
class Derived: public Base { ... };
Derived d;
Base *pb = &d;

ここでは、派生クラスオブジェクトへの基本クラスポインタを作成しているだけですが、2つのポインタが同じでない場合があります。その場合、実行時にDerived*ポインターにオフセットが適用され、正しいBase*ポインター値が取得されます。

この最後の例は、単一のオブジェクト(たとえば、タイプのオブジェクトDerived)が複数のアドレス(たとえば、Base*ポインターによってポイントされたときのアドレスとポインターによってポイントされたときのアドレス)を持つ可能性があることを示していDerived*ます。

これは少し理解しにくいです。基本クラスへのポインターは、実行時に派生クラスのオブジェクトを指すことができることを知っています。これは、ポリモーフィズムまたは動的バインディングと呼ばれます。しかし、派生クラスオブジェクトは実際にメモリ内に複数のアドレスを持っていますか?

ここで誤解があると思います。誰かがいくつかの説明をすることができますか?多分これは、C ++コンパイラでポリモーフィズムがどのように実装されているかと関係がありますか?

4

2 に答える 2

16

やってみなよ:

class B1
{
    int i;
};

class B2
{
    int i;
};

class D : public B1, public B2
{
    int i;
};

int
main()
{
    D aD;
    std::cout << &aD << std::endl;
    std::cout << static_cast<B1*>( &aD ) << std::endl;
    std::cout << static_cast<B2*>( &aD ) << std::endl;
    return 0;
}

B1サブオブジェクトがサブオブジェクトと同じアドレスを持つことはあり得ませんB2

于 2013-02-08T16:03:34.340 に答える
5

オブジェクトのアドレスは 1 つだけです。それがメモリ内の場所です。基本サブオブジェクトへのポインターを作成すると、そのサブオブジェクトのアドレスが取得されます。これは、それを含むオブジェクトのアドレスと同じである必要はありません。より簡単な例:

struct S {
    int i;
    int j;
};

S s;

の住所は の住所とsは異なりますs.j

同様に、ベース サブオブジェクトのアドレスは、派生オブジェクトのアドレスと同じである必要はありません。単一継承は通常そうですが、多重継承が有効になると、空の基本クラスを無視して、基本サブオブジェクトの最大 1 つが派生オブジェクトと同じアドレスを持つことができます。したがって、派生オブジェクトへのポインターをそのベースの 1 つへのポインターに変換する場合、派生オブジェクトのアドレスと同じ値が得られるとは限りません。

于 2013-02-08T16:03:06.557 に答える