在运行时访问v表
Access v-table at run-time
是否可以在运行时访问函数的v表?是否可以确定诸如不同功能版本的数量之类的元信息?这可能更像是一个理论问题,但是开发人员是否可以通过确保v-table永远不会超过一定的行数来限制可以扩展给定基类的类的数量?
是否可以在运行时访问函数的v表?是否可以确定诸如不同功能版本的数量之类的元信息?
不以可移植的方式。该标准甚至没有虚拟表的概念,它更多的是实现细节而不是需求,即使我知道的所有实现都使用虚表。在一般情况下,在运行时甚至没有足够的信息可用(即编译器不需要在虚表中存储条目的数量,因为它看到类型并可以计数)
开发人员是否可以通过确保v-table永远不会超过一定数量的行来限制可以扩展给定基类的类的数量?
还是没有,但由于这显示了一种误解,可能值得将其分开处理。当基类有任何虚函数时,编译器(在所有使用虚表的实现中)将创建虚函数表,并且该虚函数表在基类中每个虚函数只有一个条目(加上一些额外的数据——类型信息或指向它的指针,到对象开头的偏移量或其他实现细节)。当类扩展基类时,它不会向虚值表添加新元素,而是创建一个单独的虚值表(或更多,取决于类型层次结构)。如果派生函数没有添加任何新的虚函数,则派生对象的虚函数表将包含与原始虚函数表相同的元素数量。也就是说,您可以拥有巨大的继承层次结构,而不会影响虚函数表的布局。改变的是存储的typeinfo
数据和指向每个虚函数的指针,它们将引用最终重写
一个元信息,如不同函数版本的数量被确定?
No c++不支持反射你想要实现的是不可能在c++ AFAIK
理论上,是的,因为它存储在内存中,您可以访问它。在实践中,没有统一的、可移植的方法来实现它,因为编译器可以自由地以它想要的任何方式实现虚函数,所以您必须仔细研究编译器的源代码,以找出如何/在哪里访问所需的信息以及如何解释它。
对于您的努力,我能想到的唯一一线希望就是dynamic_cast的处理。每个具有相应库支持的编译器都有一些遍历层次结构以实现动态强制转换的概念。如果可以钩入该遍历,那么就可以知道正在处理多少层继承。也就是说,即使您做到了这一点,它也是特定于编译器的(正如其他人所说),因为这样的实现是专有的。
您可以使用调试接口访问SDK或其他调试支持接口(gdb)进行此类操作。
RTT数据更易于移植,但可能没有足够的细节用于您的项目。
对于限制v-table并防止其过度扩展的具体问题,您可以尝试以下方法;
IDiaSymbol: get_classParente 检索对该符号的类父类的引用。
HRESULT get_classParent (IDiaSymbol** pRetVal);
你可以在这里调查所有与类相关的符号类型,你可能想要做的是枚举所有加载的类类型,get_clasparent递归地并保留所有扩展基类的类计数。
你的类也可以要求符号在启动时可用,以帮助执行
- 通过switch和static_cast访问多态对象的运行时类型
- 从反向顺序C++访问矢量时运行时出错
- 运行时多态性 - 箭头运算符访问了错误的成员?
- 以这种方式在运行时访问元组的性能成本
- 在C++中使用链表的堆栈实现中,访问结构体headNode成员count和top会导致运行时错误
- 在VS2015中访问类成员时运行时错误,但在Linux上未访问时出错
- 访问使用 Bazel 构建的应用程序中的运行时文件
- 在运行时C++11 个索引模板参数包,以便访问第 N 种类型
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 访问导致运行时错误的动态数组
- 在C 中运行时从指针访问对象实例
- 如何避免对编译后无法访问的正在运行的代码部分进行运行时检查?
- 是否可以在运行时选择可以访问类的私有成员的函数
- 目标C运行时访问屏幕尺寸
- 为什么会出现访问冲突运行时错误
- C 运行时字段访问
- C 运行时成员函数通过字符串名称访问
- 在运行时按索引访问 std::tuple 元素的最佳方法
- 运行时错误0xC0000005 - 访问冲突
- 插入[n X n]矩阵类型的数据,并在运行时对其进行访问.将std::映射工作