作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如果正确完成,请忽略#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>?它是否发生在 Label 1
的调用检查期间?
编辑::
因为标签 1 似乎是赠品,只是让它对编译器来说更加模糊。请参阅上面的编辑代码。现在编译器什么时候在什么地方做?
最佳答案
是的,你说得很对。
要完全了解情况,您必须知道编译器在两点上知道什么:
内部函数 f()
(1) 编译器知道 C 和 A 的确切二进制布局以及如何从 C* 转换为 A*,并将在调用站点(标签 1)执行此操作
(2) 然而,在函数 f() 内部,编译器仅(需要)知道 A*,因此将自身限制为 A 的成员(在本例中为 int a),并且不会混淆是否特定实例是否是其他任何事物的一部分。
关于C++ 多重继承内存寻址问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10056790/
我是一名优秀的程序员,十分优秀!