13

在“Effective C++”(第 3 版,第 118 页)的第 27 项中,Scott Meyers 说:

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

这里我们只是创建了一个指向派生类对象的基类指针,但有时,这两个指针并不相同。在这种情况下,将在运行时将偏移量应用于Derived*指针以获得正确的Base*指针值。

最后一个例子说明了单个对象(例如,类型为 的对象Derived)可能有多个地址(例如,当Base*指针指向时它的地址和当指针指向时它的地址Derived*)。

这里有点难以理解。我知道指向基类的指针可以在运行时指向派生类的对象,这称为多态或动态绑定。但是派生类对象在内存中真的有超过 1 个地址吗?

我想我在这里有一些误解。有人可以澄清一下吗?也许这与 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

一个对象只有一个地址;那就是它在内存中的位置。当您创建一个指向基本子对象的指针时,您将获得该子对象的地址,并且该地址不必与包含它的对象的地址相同。一个更简单的例子:

struct S {
    int i;
    int j;
};

S s;

的地址s将不同于 的地址s.j

类似地,基本子对象的地址不必与派生对象的地址相同。通常是单继承,但是当多继承发挥作用时,忽略空基类,最多一个基子对象可以与派生对象具有相同的地址。因此,当您将指向派生对象的指针转换为指向其基数之一的指针时,您不一定会获得与派生对象的地址相同的值。

于 2013-02-08T16:03:06.557 回答