有人可以解释这个不同类的虚拟表是如何存储在内存中的吗?当我们使用指针调用函数时,他们如何使用地址位置调用函数?我们可以使用类指针获取这些虚拟表内存分配大小吗?我想看看一个类的虚拟表使用了多少内存块.我怎么能看到它?
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++ 程序,它在执行二进制文件时读取配置文件,根据配置文件创建许多子类实例,然后定期迭代这些实例并调用它们各自的虚拟函数。
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) 在这样的 TU 中
\n#include "Foo.hpp"\nint main() {\n // stuff\n Foo* foo{new Foo{}};\n foo->foo();\n // stuff\n}\nRun Code Online (Sandbox Code Playgroud)\n其中Foo.hpp包含
#pragma once\nstruct Foo {\n virtual void foo(); // implmented somewhere\n};\nRun Code Online (Sandbox Code Playgroud)\n除了调用之外不会Foo::foo发生任何事情,对吗?fooisvirtual并且 it 也不是类 are final,所以是的,在另一个TU 中可能存在派生类的对象,等等,但是......就这个 TU 而言,我认为调用override foo是非常清楚的。我不明白事情会怎样。foo->foo()Foo::foo()
那为什么生成的程序集是这样的呢?
\nmain: # @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
我正在从虚拟表中的地址调用虚函数作为练习,以测试我对该概念的理解.但是,一旦我认为我在理解虚拟方法表时取得了突破,我就遇到了另一个我不明白的问题.
在下面的代码中,我创建了一个名为的类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
我下面这个教程,试图了解virtual table背后的整个过程pointer和virtual 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?
我想念这一点.花哨的例子?