是' final'说明符添加任何开销?

时间:2015-08-12 14:12:22

标签: c++ c++11 c++14

finalclass上使用说明符function是否会添加任何内存或CPU开销,或仅在编译时使用?

std::is_final如何识别最终的内容?

2 个答案:

答案 0 :(得分:22)

它实际上可以减少开销。在极少数情况下,增加它。

如果您有指向finalA的指针,则可以对任何虚拟方法调用进行反虚拟化并直接调用。同样,可以对虚拟final方法的调用进行去虚拟化。此外,final类的继承树是固定的,即使它包含virtual个父类,因此您可以对某些父访问进行去虚拟化。

这些去虚拟化中的每一个都减少或消除了查询运行时结构(vtable)的要求。

可能会有轻微的下行空间。某些编码技术依赖于vtable访问以避免直接访问符号,然后不导出符号。访问vtable可以通过约定完成(没有来自库的符号,只有相关类的头文件),而访问方法直接涉及链接到该符号。

这打破了一种形式的动态C ++库链接(在这种情况下,你可以避免链接多于一个dll加载符号和/或返回指针的C连接函数,并通过它们的vtable导出类。)

如果您链接动态库中的符号,动态库符号加载也可能比vtable查找更昂贵。我没有经历或描述过这个,但我看到它声称。一般来说,收益应该超过这些成本。任何此类成本都是实施质量问题,因为该方法不是final,因此不会强制要求发生成本。

最后,final禁止类上的空基本优化技巧,其中某人知道你的类没有状态,并从中继承以减少"存储"类的实例,从1个字节到0个字节。如果您的类为空并且不包含虚拟方法/继承,请不要使用final来避免此类被阻止。 final函数没有等价物。

除了EBO优化问题(仅在空类型中出现),final的任何开销都来自其他代码与其交互的方式,并且很少见。更常见的是,它会使其他代码更快,因为直接与方法交互可以更直接地调用方法,并且可以导致连锁优化(因为编译器可以更充分地理解调用)。 p>

除了final之外的任何其他类型的标记,它在运行时几乎肯定是无害的。在具有虚函数和继承的类上执行此操作可能在运行时很有用。

std::is_final和类似的特征几乎都是通过编译器内置魔法实现的。 std中的大量特征需要这样的魔力。请参阅How to detect if a class is final in C++11?(感谢@Csq查找)

答案 1 :(得分:4)

  1. 不,它仅在编译时使用

  2. 魔术(see here了解更多信息 - 感谢Csq提供链接)