c++ - C++中虚方法表存储在哪里?

标签 c++ memory virtual

我想知道类对象(不是实例,而是类)如何存储在内存中?

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 的类对象(如果我理解正确的话)。 如果我们更深入(尝试使用 clanggcc),我们可以看到类似的东西(同样,标准中没有强烈描述):

A
    vtptr*
    int a
B
    vtptr*
    int b

好的,现在我们看到 ab 属性存储在哪里。我们还看到了指向虚方法表的指针。但是vtptr*(虚方法表)实际存储在哪里呢?为什么不靠近类(class)?或者它确实如此?

此外,还有另一个问题:我能够通过更改指针来更改虚方法表(简单逻辑)。我还可以安全地更改指向其方法的指针吗?

附言在您的问题中,您可以回答 gcc 和 clang。 附言如果我在某处有误,请在您的回答中指出。

最佳答案

C++标准并没有规定虚函数机制应该如何实现。实际上,所有 C++ 实现都为每个类使用一个虚函数表,并在具有虚函数的类(称为多态类)的每个对象中使用一个虚函数表指针。但细节可能有所不同,特别是对于多重继承和虚拟继承。

你可以在斯坦利·李普曼的经典著作Inside The C++ Object Model中了解常见的选择。 .

询问虚函数表存储在“何处”没有多大意义。它很像任何静态变量:它的位置取决于实现并且几乎是任意的。而关于

Why not near with the classes?

...这样的类没有存储在任何地方,它们不是对象,所以这没有意义,抱歉。

对于给定的实现,您可以更有意义地询问每个对象中的 vtable 指针存储在哪里?

通常这是在对象的开头,但如果您从非多态类派生,并添加一个虚函数,那么您可能会在其他地方获得 vtable 指针。或不。后一种可能性是 Derived*Base*static_cast(或反之亦然)可以进行地址调整的主要原因,即不同于简单的reinterpret_cast

关于c++ - C++中虚方法表存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28849103/

相关文章:

c++ - 将游戏 handle 摇杆值转换为范围

c++ - 为什么我不能用谓词的实例化构造 std::set,但我可以分配以这种方式构造的 std::set?

performance - 如何检查应用程序是否受 CPU 限制或内存限制?

c# - C#创建派生类时,是否可以用n参数函数覆盖0参数虚函数?

linux - 具有两个域的配置 Postfix

c++ - std::vector 和多态性

c++ - 尝试渲染像素坐标时,简单的线条渲染失败

存储在共享内存中的 C++ 对象(volatile 成员函数?)

java - 使用显示 :table jSTL tag 的内存使用问题

c++ - 虚拟数据类型/枚举