gpt4 book ai didi

c++ - 在这种情况下是否可以避免使用虚拟方法调用?

转载 作者:IT老高 更新时间:2023-10-28 21:55:51 24 4
gpt4 key购买 nike

我有一种数据必须存储在一个连续的数组中,该数组被迭代以更新该数据。棘手的部分是我希望能够动态更改任何对象的更新方式。

这是我目前想出的:

struct Update {
virtual void operator()(Data & data) {}
};

struct Data {
int a, b, c;
Update * update;
};

struct SpecialBehavior : public Update {
void operator()(Data & data) override { ... }
};

然后我会为每个数据对象分配某种类型的更新。然后在更新期间所有数据都被传递给它自己的更新仿函数:

for (Data & data : all)
data->update(data);

据我所知,这被称为策略模式。

我的问题:有什么方法可以更有效地做到这一点吗?有什么方法可以在不调用虚方法的情况下实现同样的灵 active ?

最佳答案

虚函数调用的开销是多少?好吧,实现必须做两件事:

  1. 从对象加载 vtable 指针。
  2. 从 vtable 加载函数指针。

这正是两个内存间接。您可以通过将函数指针直接放在对象中(避免从对象中查找 vtable 指针)来避免两者中的一种,这是 ralismarks answer 给出的方法.

这有一个缺点,它只适用于单个虚函数,如果你添加更多,你会用函数指针膨胀你的对象,导致你的缓存压力更大,因此可能会降低性能。只要你只是替换一个虚函数,没关系,再添加三个,你的对象就膨胀了 24 个字节。


除非您确保编译器可以导出 Update 的真实类型,否则无法避免第二次内存间接寻址。在编译时。而且由于这似乎是使用虚函数在运行时执行决策的全部意义所在,因此您很不走运:任何“删除”该间接性的尝试都会产生更差的性能。

(我在引号中说“删除”,因为您当然可以避免从内存中查找函数指针。代价是您正在执行类似 switch()else if() 梯形图的某些类型标识值 从对象加载,这将比仅仅从对象加载函数指针成本更高。ralismarks answer 中的第二个解决方案明确地做到了这一点,而 Vittorio Romeostd::variant<> 方法隐藏了它在 std::variant<> 模板中。间接并没有真正删除,它只是隐藏在更慢的操作中。)

关于c++ - 在这种情况下是否可以避免使用虚拟方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43540005/

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