请忽略 #include 部分,假设它们已正确完成。这也可能是特定于实现的(但 vtables 的概念也是如此),但我只是好奇,因为它增强了我对多重继承的可视化。(顺便说一下,我使用的是 MinGW 4.4.0)
初始代码:
class A {
public:
A() : a(0) {}
int a;
};
//Edit: adding this definition instead
void f(void* ptrA) {
std::cout<<((A*)ptrA)->a;
}
//end of editing of original posted code
#if 0
//this was originally posted. Edited and replaced by the above f() definition
void f(A* ptrA) {
std::cout<<ptrA->a;
}
#endif
这是编译并生成目标代码。
在我使用的其他一些编译单元中(在包含上述代码的头文件之后):
class C : public B , public A {
public:
int c;
}objC;
f(&objC); // ################## Label 1
objC 的内存模型:
//<1> stuff from B
//<2> stuff from B
//<3> stuff from A : int a
//<4> stuff from C : int c
&objC
将在上面假设的内存模型中包含 <1> 的起始地址,编译器如何/何时将其转移到 <3>?是否在检查 call at 期间发生Label 1
?
编辑::
因为 Lable 1 似乎是一个赠品,只是让它对编译器来说更加模糊。请参阅上面的编辑代码。现在编译器什么时候做,在哪里做?