c++ - vtable中虚拟函数的地址

标签 c++

假设有一个名为 Person 的类,其中包含一个名为age() 的虚函数。根据语言语义,vtable 是每个类而不是每个对象。它是 VPTR,它是每个对象的并指向 vtable。

问题:

如果我构建这个程序(假设 main() 存在):

  1. 是否会创建 vtable,即 vtable 是否可以在不创建单个对象的情况下存在?

  2. 编译器为age()放入vtable中的地址是内存中的某种静态地址吗?

  3. 或者编译器内部创建一些对象来获取age()的地址(因为age()将处理一些只有在构造对象时才存在的数据成员)或者有这背后还有其他魔法吗?

据我了解,答案如下:

  1. 不确定

我尝试在上面的程序上运行“nm”只是为了看看我是否能找出虚函数表,但没有运气。有没有办法做到这一点?

请提出建议。

最佳答案

由于所有实现都是定义的,我的回答描述了一些“常见实现”

  1. v-table 就像机器代码本身一样存储在可执行文件中,并由操作系统加载程序加载到内存中。操作系统不关心加载什么数据:字符串文字、机器代码、虚函数表、常量数据等...

  2. 假设您有:

    struct A {
        int x;
        virtual void f() { cout << x; }
    };
    
    void g(A* a) { a->f(); }
    

    生成的代码看起来(语义上)类似于:

    // pseudocode, not C++
    struct A {
        void *vtable;
        int x;
    };
    
    void A_f(A* this) { cout << this->x; }
    
    void* A_vtable[] = { &A_f };
    
    void g(A* a) { ((void(*)(A*))(((void**)a->vtable)[0]))(a); }
    

    所以是的,它是静态数据。

    当然上面的代码是非常简化的。要支持 RTTI 和虚拟继承,您必须做更复杂的事情。

  3. 我不明白你的意思,但是不行。

关于c++ - vtable中虚拟函数的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8682998/

相关文章:

c++ - 分离线程 : mutex destroyed while busy Error C++

c++ - 对 'dlsym' 的 undefined reference

C++/QT/ARM 处理器交叉编译/编程

iphone - 我可以将 CAArchive 类添加到我的 iPhone 项目以序列化数据吗?如果是这样,如何?

c++ - 如何将变量与字符串值组合

c++ - Visual Studio 中带有 Autos 变量的锁定图标。它表示什么?

c++ - 扩展 auto_ptr 以释放一个 C 风格的对象

c++ - 如何计算结构 vector (这是一个类成员,使用提取运算符)

c++ - cout 打印字符串变量无法通过构建

c++ - std::thread 参数(值与常量)