在“Effective C ++”(第3版,第118页)的第27项中,Scott Meyers说:
class Base { ... };
class Derived: public Base { ... };
Derived d;
Base *pb = &d;
这里我们只是创建一个指向派生类对象的基类指针,但有时候,两个指针不会相同。在这种情况下,在运行时向
Derived*
指针应用偏移量以获得正确的Base*
指针值。最后一个示例演示了单个对象(例如,类型为
Derived
的对象)可能具有多个地址(例如,当Base*
指针指向时其地址及其地址由Derived*
指针指向。
这有点难以理解。我知道指向基类的指针可以在运行时指向派生类的对象,这称为多态或动态绑定。但是派生类对象在内存中确实有多个地址吗?
猜猜我在这里有一些误解。有人可以澄清一下吗?也许这与如何在C ++编译器中实现多态性有关?
答案 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
的地址不同。
类似地,基础子对象的地址不必与派生对象的地址相同。单继承通常是,但是当多重继承发挥作用并忽略空基类时,最多一个基础子对象可以具有与派生对象相同的地址。因此,当您将指向派生对象的指针转换为指向其中一个基础的指针时,您不一定会获得与派生对象的地址相同的值。