标签: virtual-table

虚拟表和_vptr存储方案

有人可以解释这个不同类的虚拟表是如何存储在内存中的吗?当我们使用指针调用函数时,他们如何使用地址位置调用函数?我们可以使用类指针获取这些虚拟表内存分配大小吗?我想看看一个类的虚拟表使用了多少内存块.我怎么能看到它?

class Base
{
public:
    FunctionPointer *__vptr;
    virtual void function1() {};
    virtual void function2() {};
};

class D1: public Base
{
public:
    virtual void function1() {};
};

class D2: public Base
{
public:
    virtual void function2() {};
};
int main()
{
    D1 d1;
    Base *dPtr = &d1;
    dPtr->function1();
}
Run Code Online (Sandbox Code Playgroud)

谢谢!提前

c++ vtable vptr virtual-table

6
推荐指数
1
解决办法
897
查看次数

避免重复的 C++ 虚拟表查找

我有 C++ 程序,它在执行二进制文件时读取配置文件,根据配置文件创建许多子类实例,然后定期迭代这些实例并调用它们各自的虚拟函数。

Gprof 告诉我这些函数调用占用了很多时间(前面提到的迭代发生得非常频繁),所以我想以某种方式尽量避免重复的虚函数调用。

代码类似于以下内容。一旦程序在程序开始时填充向量 v,该向量在程序的其余部分将不再改变,因此每次我想调用 f() 时重复执行虚拟表查找似乎效率低下。我认为必须有一种方法可以以某种方式缓存或保存函数指针,但我不确定如何。

希望您有任何关于加快速度的建议。谢谢!

编辑:对不起,我忘了提到函数调用 f() 的子实例向量必须按照从 0 到 v.size() - 1 的顺序,所以我不能将 v 的元素组合在一起相同的派生类型。

此外,这是用 -O3 -std=c++14 构建的

class Parent {
public:
    virtual void f() { } 
};

class Child1 : public Parent {
public:
    void f() { /* do stuff for child1 */ }
};

//...

class Child9 : public Parent {
public:
    void f() { /* do stuff for child9 */ }
};

int main() {
    vector<Parent*> v;

    // read config …
Run Code Online (Sandbox Code Playgroud)

c++ optimization virtual-functions vtable virtual-table

6
推荐指数
1
解决办法
509
查看次数

为什么虚拟成员函数会影响实际上不需要虚拟调度的 TU 的编译代码?

在这样的 TU 中

\n
#include "Foo.hpp"\nint main() {\n    // stuff\n    Foo* foo{new Foo{}};\n    foo->foo();\n    // stuff\n}\n
Run Code Online (Sandbox Code Playgroud)\n

其中Foo.hpp包含

\n
#pragma once\nstruct Foo {\n    virtual void foo(); // implmented somewhere\n};\n
Run Code Online (Sandbox Code Playgroud)\n

除了调用之外不会Foo::foo发生任何事情,对吗?fooisvirtual并且 it 也不是类 are final,所以是的,在另一个TU 中可能存在派生类的对象,等等,但是......就这个 TU 而言,我认为调用override foo是非常清楚的。我不明白事情会怎样。foo->foo()Foo::foo()

\n

那为什么生成的程序集是这样的呢?

\n
main:                                   # @main\n        push    rax\n        mov     edi, 8\n        call    operator new(unsigned long)@PLT\n        mov     rcx, qword ptr [rip + vtable for Foo@GOTPCREL]\n        add     rcx, …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance virtual-functions dynamic-dispatch virtual-table

2
推荐指数
1
解决办法
84
查看次数

为什么函数使用存储在虚方法表中的地址调用虚函数返回垃圾?

我正在从虚拟表中的地址调用虚函数作为练习,以测试我对该概念的理解.但是,一旦我认为我在理解虚拟方法表时取得了突破,我就遇到了另一个我不明白的问题.

在下面的代码中,我创建了一个名为的类Car,它包含一个成员变量x和两个虚函数,第一个和第二个.现在,我通过黑客攻击虚拟表来调用这两个虚拟方法.第一个函数返回正确的答案,但第二个函数返回一些随机值或垃圾,而不是它初始化的内容.

#include <cstdio>

class Car
{
private:
    int x;

    virtual int first()
    {
        printf("IT WORKS!!\n");
        int num = 5;
        return num;
    }
    virtual int second()
    {
        printf("IT WORKS 2!!\n");
        //int num  = 5;
        return x;
    }


public:

    Car(){
        x = 2;
    }
};

int main()
{
    Car car;
    void* carPtr = &car;
    long **mVtable =(long **)(carPtr);

    printf("VTable: %p\n", *mVtable);
    printf("First Entry of VTable: %p\n", (void*) mVtable[0][0]);
    printf("Second Entry of VTable: %p\n", (void*) mVtable[0][1]);

    if(sizeof(void*) == 8){
        printf("64 …
Run Code Online (Sandbox Code Playgroud)

c++ virtual-functions member-function-pointers c++14 virtual-table

1
推荐指数
1
解决办法
138
查看次数

为什么在运行时需要虚拟表来调用虚函数?

我下面这个教程,试图了解virtual table背后的整个过程pointervirtual functions in C++.

不确定,当我有这样的代码:

D1 d1;
Base *dPtr = &d1;
dPtr->function1();
Run Code Online (Sandbox Code Playgroud)

为什么我需要所有这些virtual table管理?为什么编译器根本不分配内存地址d1(或基数,如果没有)覆盖virtual function

我的意思是:如果它需要D1 functon1()地址或Base functon1()地址,它可以在编译时详细说明.它当时知道.为什么以后在运行时看到会浪费时间和资源virtual tables

我想念这一点.花哨的例子?

c++ polymorphism virtual-functions virtual-table

0
推荐指数
1
解决办法
86
查看次数