给定这两种类型,我是否可以确定虚拟函数是否已被覆盖?
Given both types, can I determine if a virtual function have been overridden?
我正在设计一个由模块集合构建的系统。 基Module
类具有一组虚拟函数,默认情况下这些函数不执行任何操作,但如果需要,可以在派生模块类中重写。
例如,其中一个函数是OnUpdate()
。 目前,当更新发生时,我遍历所有模块并在每个模块上运行此功能。 当然,这会导致对任何不覆盖相关函数的模块进行许多"浪费"调用。
鉴于大多数模块不会覆盖大多数成员函数(并且分析表明这是我系统中的瓶颈(,我更愿意做的是跟踪哪些模块会覆盖成员函数并仅执行这些模块。 目前,我计划仅保留那些需要运行的模块指针的额外向量。
我的问题是收集此信息需要我检测模块是否已覆盖每个成员函数。 当我知道我正在使用的确切派生类型时,我可以对模块创建进行此分析,所以我认为这应该是可能的,但我期望工作的测试却没有。
下面是一些失败的简化检测代码:
template <typename T>
T & AddModule() {
static_assert(std::is_base_of<Module, T>,
"AddModule() can only take module types.");
// Create the new module and store it.
auto mod_ptr = std::make_shared<T>();
modules.push_back(mod_ptr);
// If the module has OnUpdate() track it!
// *** This test is not working! ***
if (&T::OnUpdate != &Module::OnUpdate) {
on_update_mods.push_back(mod_ptr);
}
// ...lots more tests here...
return *mod_ptr;
}
是否有其他方法可以处理此检测?
我也很高兴听到关于如何实现我的目标的替代想法。 我绝对希望模块编写者能够轻松地简单地实现任何指定的函数,并根据需要调用它们。
到目前为止,我想出的唯一其他选择是不要在模块基类中拥有虚函数,然后使用 SFINAE 在派生类中检测它们,然后将它们包装在 lambda 中并存储要运行的函子向量。 我认为这将起作用,但它会稍微慢一些(函子的间接性更多(并且更容易出错(现在如果您在成员函数名称中输入错误,覆盖关键字将抛出错误......
这个问题确实与这个问题相似,但提供的解决方案对我不起作用。 第一个选项要求在构造函数中单独标识所有工作成员函数,我可能正在使用数十个或更多,因此这很容易出错。 第二个选项让函数返回一个布尔值,但仅在运行时相关,并且在不需要它们时我无法运行它们。
我最终找到了解决这个问题的方法,让我得到了合理的加速。 具体来说,对于每个虚拟成员函数,我在基类中保留一个布尔值,指示该函数是否已被覆盖。 这些布尔值中的每一个都默认为 true,但成员函数的基本实现在执行时将其设置为 false(因为只有在函数未被覆盖的情况下才会运行(。
我定期扫描并更新我的向量,删除任何已被证明不存在的成员函数。
最终结果,~10% 加速,无需更改派生模块本身。 没有我希望的那么快,但考虑到这是一个科学软件,有些运行需要一个月,减少几天的休息时间肯定会有所帮助。
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 函数作为模板参数,是否对返回类型强制约束
- visual是否可以在c++中创建一个接收无限数量相同类型(或至少相当数量)参数的函数
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 函数是否可以访问传递给main()的参数
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 在这种情况下,java对象是否可以调用本机函数
- 检查函数返回类型是否与STL容器类型值相同
- 根据某个函数是否存在启用模板
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 无论如何,我可以确定构造函数是否存在吗?
- 是否可以将函数导入命名空间,但不能导出它?
- 返回指向对象的指针的函数调用是否为 prvalue?
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本