派生类对象的多个地址?

时间:2013-02-08 15:57:25

标签: c++ polymorphism

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

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

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

     

最后一个示例演示了单个对象(例如,类型为Derived的对象)可能具有多个地址(例如,当Base*指针指向时其地址及其地址由Derived*指针指向。

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

猜猜我在这里有一些误解。有人可以澄清一下吗?也许这与如何在C ++编译器中实现多态性有关?

2 个答案:

答案 0 :(得分: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子对象。

答案 1 :(得分:5)

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

struct S {
    int i;
    int j;
};

S s;

s的地址将与s.j的地址不同。

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