gpt4 book ai didi

c++ - 虚拟函数和vtable如何实现?

转载 作者:行者123 更新时间:2023-12-03 07:03:40 26 4
gpt4 key购买 nike

我们都知道C++中的虚函数,但是如何在深层次上实现它们呢?

是否可以在运行时修改vtable甚至直接访问它?

vtable是否适用于所有类,或者仅适用于至少具有一个虚函数的类?

对于至少一个条目的函数指针,抽象类是否仅具有NULL?

拥有一个虚拟函数会减慢整个类(class)吗?还是仅调用虚拟函数?如果虚拟函数是否被实际覆盖,速度是否会受到影响?或者,只要它是虚拟的,对速度没有影响。

最佳答案

虚拟功能如何在深层次上实现?

"Virtual Functions in C++":

Whenever a program has a virtual function declared, a v - table is constructed for the class. The v-table consists of addresses to the virtual functions for classes that contain one or more virtual functions. The object of the class containing the virtual function contains a virtual pointer that points to the base address of the virtual table in memory. Whenever there is a virtual function call, the v-table is used to resolve to the function address. An object of the class that contains one or more virtual functions contains a virtual pointer called the vptr at the very beginning of the object in the memory. Hence the size of the object in this case increases by the size of the pointer. This vptr contains the base address of the virtual table in memory. Note that virtual tables are class specific, i.e., there is only one virtual table for a class irrespective of the number of virtual functions it contains. This virtual table in turn contains the base addresses of one or more virtual functions of the class. At the time when a virtual function is called on an object, the vptr of that object provides the base address of the virtual table for that class in memory. This table is used to resolve the function call as it contains the addresses of all the virtual functions of that class. This is how dynamic binding is resolved during a virtual function call.



是否可以在运行时修改vtable甚至直接访问它?

一般来说,我相信答案是“否”。您可以进行一些内存修改来找到vtable,但是您仍然不知道函数签名的外观。无需直接访问vtable或在运行时对其进行修改,使用该功能(该语言支持)想要实现的任何事情都应该是可能的。还要注意,C++语言规范 并未规定必须使用vtable-但这是大多数编译器实现虚函数的方式。

该vtable是否适用于所有对象,或者仅适用于具有至少一个虚拟功能的对象?

我相信这里的答案是“取决于实现”,因为该规范首先不需要vtables。但是,实际上,我相信所有现代编译器仅在一个类至少具有1个虚函数的情况下才创建vtable。与vtable相关联的空间开销与与调用虚拟函数与非虚拟函数相关的时间开销。

对于至少一个条目的函数指针,抽象类是否仅具有NULL?

答案是语言规范未指定,因此取决于实现。如果未定义(通常是未定义),则调用纯虚函数会导致未定义行为(ISO / IEC 14882:2003 10.4-2)。实际上,它确实在vtable中为该功能分配了一个插槽,但并未为其分配地址。这使vtable不完整,这要求派生类实现该功能并完成vtable。有些实现只是在vtable条目中放置了一个NULL指针。其他实现则将指针指向执行与声明类似的操作的虚拟方法。

请注意,抽象类可以定义纯虚函数的实现,但是只能使用限定ID语法来调用该函数(即,在方法名称中完全指定该类,类似于从一个类中调用基类方法。派生类)。这样做是为了提供易于使用的默认实现,同时仍然需要派生类提供替代。

拥有单个虚拟函数会降低整个类的速度,还是只会降低对虚拟函数的调用?

这已经成为我所掌握的知识,所以如果我错了,请有人在这里帮助我!

我相信只有类中的虚拟函数会遇到与调用虚拟函数和非虚拟函数有关的时间性能损失。该类的空间开销是任意一种。请注意,如果有一个vtable,则每个类只有1个,而不是每个对象一个。

如果虚拟函数实际上被覆盖或不被覆盖,速度是否会受到影响?或者,只要它是虚拟的,对速度没有影响吗?

我不相信被覆盖的虚函数的执行时间与调用基本虚函数相比会减少。但是,与为派生类和基类定义另一个vtable关联的类存在额外的空间开销。

其他资源:

http://www.codersource.net/published/view/325/virtual_functions_in.aspx(通过返回机器)
http://en.wikipedia.org/wiki/Virtual_table
http://www.codesourcery.com/public/cxx-abi/abi.html#vtable

关于c++ - 虚拟函数和vtable如何实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64041627/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com