【发布时间】:2015-05-05 03:00:33
【问题描述】:
我想知道类对象(不是实例,而是类)如何存储在内存中?
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...
其中 AB 是 B 的类对象(如果我理解正确的话)。 如果我们更深入(尝试使用 clang 和 gcc),我们可以看到类似的东西(同样,标准中没有强烈描述):
A
vtptr*
int a
B
vtptr*
int b
好的,现在我们看看a 和b 属性存储在哪里。我们还看到了指向虚拟方法表的指针。但是vtptr*(虚拟方法表)实际存储在哪里?为什么不靠近上课?还是有?
另外,这是另一个问题:我能够通过更改指针来更改虚拟方法表(简单逻辑)。我也可以安全地更改指向它的方法的指针吗?
附:在您的问题中,您可以回答 gcc 和 clang。 附言如果我在某个地方错了,请在您的答案中指出。
【问题讨论】:
-
虽然您可能会发现类似的实现,但这取决于实现。您必须指定编译器才能获得合理的答案。
-
vtables 不存储在对象中,因为它在内存方面效率非常低。但是,标准中没有任何内容会阻止实现这样做。我理解你的好奇心,但只要你编写的是健全的代码,你应该很少(如果有的话)担心实现细节。此外,弄乱 vtable 或 vtptrs(以及做任何没有被标准严格定义的事情)永远不会被认为是安全的。
-
如果你看看
g++ -fdump-class-hierarchy -c filename.cpp的结果,也许你会明白一点 -
在某些地方你使用类来表示实例(例如为什么不靠近类)。这对我来说很奇怪,因为您在第一句话中专门从类中描述了实例。