我有一些课程:
class I
{
public:
virtual void foo() = 0;
protected:
virtual ~I(){}
};
此类不提供实例删除的接口,因此使析构函数保护是非常合理的解决方案。因此,不必将析构函数设为虚拟。但我有代码,它是虚拟的。
它看起来不是一个大错误,但它对代码性能有显着影响吗? 当我们创建虚拟功能时,我们再向虚拟功能表添加一条记录,当我们进行虚拟呼叫时,我们会在此表中搜索。所以这意味着查找时间会增加。我对吗?
答案 0 :(得分:5)
即使这是一个问题(它不是),不,它不会增加时间。查找不是运行时实际查找任何内容 - 无论vftable有多大都无关紧要。它确切知道在表格中跳转的位置。
所以 - 调用virtual
方法需要花费一些费用 - 实际查询不需要任何费用。
答案 1 :(得分:2)
通常,在处理多态类时,应始终将析构函数声明为virtual
。否则你将会遇到以下经典问题:
Base *derived = new Derived();
delete derived;
与代码中存在潜在问题相比,对性能的担忧无疑是无关紧要的。今天你不需要删除这个对象,也许明天就可以了,如果你忘了这个,你最终会产生微妙的错误。
virtual
调用的成本存在,但除非每秒调用数百万个虚方法,否则不应该担心。
虽然在vtable中查找方法不是运行时操作,但它是一个编译时操作。编译完成后,您的代码已经知道vtable的哪个索引被指定的方法占用。花费的时间是从vtable获取函数地址的间接方式。
答案 2 :(得分:0)
好的答案。虚拟函数调用的成本就像是猿上的一根头发。
但是,析构函数通常可以是慢速的,虚拟的或非虚拟的,因为它很容易使数据和类结构过于复杂,所以当你删除某些内容时,它可以运行27米的软件,你没有甚至意识到它正在做。