C ++编译器如何处理具有多重继承的偏移?

时间:2014-06-05 18:29:17

标签: c++

当我试图表达我的问题时,请耐心等待。我猜我试图理解的东西是这样的:

class Base1 { public: int value { 5 }; };
class Base2 { /* fields */ };

class Derived1 : public Base1 { ... };
class Derived2 : public Base2, public Derived1 { ... };

编译器如何解决像这样的代码的内存偏移?

void base1_action(Base1 *instance) { 
    cout << instance->value << endl;
}

void change_base(Base2* instance) {
    base1_action(reinterpret_cast<Base1*>(instance));
}

int main() {
    Base2* instance = new Derived2;
    change_base(instance);
}

也就是说,如果在main中实际对象实例的类型为Derived2,则当change_base中的基本更改从Base2发送到Base1时,编译器如何能够知道如何重新计算对象的偏移量,以便在调用base1_action时,它会获得指向Base1的正确偏移量的指针?

换句话说,当存在多个继承时,编译器如何能够计算从一个基类到另一个基类的偏移量(而不是从已知派生类计算基类偏移量的更简单问题)? / p>

希望我的问题有点清楚 - 谢谢!

2 个答案:

答案 0 :(得分:5)

base1_action(reinterpret_cast<Base1*>(instance));

&#34;编译器如何知道如何重新计算对象的偏移量&#34;

它没有。您正在使用reinterpret_cast,这意味着类似于&#34;这里是一种类型的位,现在将其视为其他类型的位&#34;。这里没有涉及偏移计算。换句话说:这是代码中的错误。

如果您要编写static_castdynamic_cast,编译器确实需要计算偏移量。由于它知道类型和类型的内存布局,因此可以轻松地添加或减去正确的偏移量。如果您要隐藏类型,例如通过在void *之前将指针分配给static_cast,则无法应用正确的偏移计算。

答案 1 :(得分:0)

它认为,GCC / MinGW会这样做:

class Base1 { public: int value { 5 }; }
class Base2 { /* fields */ }
class Derived1 : public Base1 { ... }
class Derived2 : public Base2, public Derived1 { ... }


Derived2:
    Base2 fields
    Derived1:
        Base1 fields
        Derived1 fields
    Derived2 fields