我想知道类对象(不是实例,而是类)如何存储在内存中?
class A {
public:
int a;
virtual void f();
virtual ~A();
};
class B : public A {
public:
int b;
void f() final override;
};
我知道,通常(标准没有强烈描述)在这种继承(B 派生自 A)的情况下,我们有:
memory: ....AB...
where AB是 B 的类对象(如果我理解正确的话)。
如果我们更深入(尝试过clang and gcc),我们可以看到类似的内容(同样,标准中没有强烈描述):
A
vtptr*
int a
B
vtptr*
int b
好的,现在我们看看在哪里a
and b
属性商店。而且我们还看到pointer到虚拟方法表。但哪里有vtptr*
(虚拟方法表)实际存储?为什么不离上课近一点呢?或者确实如此?
另外,这是另一个问题:我能够通过更改指针来更改虚拟方法表(简单逻辑)。我还可以安全地更改指向其方法的指针吗?
附:在您的问题中,您可以回答 gcc 和 clang。
附言如果我有什么地方错了,请在你的答案中指出。
C++标准并没有规定虚函数机制应该如何实现。实际上,所有 C++ 实现都为每个类使用一个虚函数表,并在具有虚函数的类(称为多态类)的每个对象中使用一个虚函数表指针。但细节可能有所不同,特别是对于多重继承和虚拟继承。
您可以在斯坦利·李普曼的经典著作中阅读有关常见选择的信息C++ 对象模型内部 https://rads.stackoverflow.com/amzn/click/com/0201834545.
询问虚函数表存储在“哪里”没有多大意义。它很像任何静态变量:它的位置取决于实现并且几乎是任意的。并关于
”为什么不离上课近一点呢?
…这样的类不存储在任何地方,它们不是对象,所以这没有意义,抱歉。
您可以更有意义地问,对于给定的实现,每个对象中的 vtable 指针存储在哪里?
通常它位于对象的开头,但如果您从非多态类派生并添加虚拟函数,那么您可能会在其他地方获得 vtable 指针。或不。后一种可能性是导致static_cast
of Derived*
to Base*
(或反之亦然)可以进行地址调整,即不同于简单的reinterpret_cast
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)