当我试图表达我的问题时,请耐心等待。我猜我试图理解的东西是这样的:
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>
希望我的问题有点清楚 - 谢谢!
答案 0 :(得分:5)
base1_action(reinterpret_cast<Base1*>(instance));
&#34;编译器如何知道如何重新计算对象的偏移量&#34;
它没有。您正在使用reinterpret_cast
,这意味着类似于&#34;这里是一种类型的位,现在将其视为其他类型的位&#34;。这里没有涉及偏移计算。换句话说:这是代码中的错误。
如果您要编写static_cast
或dynamic_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