游戏引擎有这个类:
class MouseListener{
public :
MouseListener();
virtual void OnMouseDown(int mx,int my);
virtual void OnMouseUp(int mx,int my);
.
.
.
};
每个想要听鼠标输入的对象都必须固有该类并覆盖它的方法。为了不必每次都声明一个新类型,该类被修改为:
class MouseListener{
public :
MouseListener();
std::function <void(MouseListener*,int,int)>OnMouseDown;
std::function <void(MouseListener*,int,int)>OnMouseUp;
.
.
.
};
现在使用这个类可以这样做:
MouseListener * m = new MouseListener();
m->OnMouseDown = [](MouseListener * thiz,int x,int y){
//// do something
};
在输入系统中,只调用非空(已分配)的MouseListener函数(使用thiz =鼠标侦听器)。 知道该类是从外部库(静态链接)使用的,这在性能方面更好吗?
注意:除非收到鼠标事件,否则不会调用这些函数,当发生这种情况时,会为每个听取鼠标输入的对象调用相应的函数(不应该是批次,&lt; 50)< /强>
答案 0 :(得分:6)
这实际上取决于虚函数与函数对象的用法。
虽然std::function
可能比虚拟调用*慢,但std::function
具有短暂的缓冲区优化,这可能会阻止动态内存分配(您可能会在虚拟内部进行分配)版本)。
这本身可能胜过你可能对常规多态性做的任何事情。
在内部(但不保证),std::function
对象无论如何都使用虚拟调用进行类型擦除,所以我说差异可以忽略不计。
提示 - 请务必检查std::function
是否有效(通过调用if(static_cast<bool>(myFunction))
)。编译器将插入一个检查以查看该函数是否为空。如果没有,程序将抛出std::bad_function_call
。开发人员检查将使编译器在启用优化时删除他的检查以及与std::bad_function_call
相关的代码,从而留下更“平滑”的汇编代码。
根据我的经验处理性能和C ++时,优化内存分配,线程间争用和错误的数据结构更加重要,这些结构对缓存起作用。通常,它比优化CPU内容更有价值的优化(比如虚函数与std::function
)
*一个不错的编译器可以将类型擦除实现为虚函数+给定的lambda作为内联函数。从理论上讲,它不应该比常规虚函数慢。另一方面,如果函数对象获得非可嵌入的可调用,如函数指针,它可以使用两个间接来启动该函数。这可能比常规虚拟呼叫慢。这取决于。