派生类对象的多个地址?

Qia*_* Xu 13 c++ polymorphism

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

class Base { ... };
class Derived: public Base { ... };
Derived d;
Base *pb = &d;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Jam*_*nze 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;
}
Run Code Online (Sandbox Code Playgroud)

B1子对象没有可能的方式与子对象具有相同的地址B2.


Pet*_*ker 5

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

struct S {
    int i;
    int j;
};

S s;
Run Code Online (Sandbox Code Playgroud)

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

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

  • @ us2012:非多态基类,多态派生类,vtable指针在派生类的偏移0处添加,后跟基类. (5认同)