虚函数上final的奇怪行为
Odd behaviour of final on a virtual function
我遇到了一个奇怪的情况,当final
关键字被添加到一个虚函数声明中,它的定义在一个单独的。cpp文件中。
考虑下面的例子:
IClass.hpp
class IClass //COM-like base interface
{
protected:
virtual ~IClass(){} //derived classes override this
public:
virtual void release() final;
};
dllmain.cpp(共享库)
#include "IClass.hpp"
...
void IClass::release()
{
delete this;
}
...
main.cpp(独立执行)
//various includes here
...
int main(int argc, char** argv)
{
/* From "IGameEngine.hpp"
class IGameEngine : public IClass
{
...
};
*/
IGameEngine* engine = factoryGameEngine();
...
engine->release();
return 0;
}
事实上,GCC 4.9.2将报告一个undefined reference to 'IClass::release()'
我的目标是将IClass::release()
作为不可重写的,同时将其实现隐藏在游戏引擎的共享库中。有什么建议吗?
对GCC对final
的使用进行了一些挖掘,结果发现虚拟函数标记为最终获得"去虚拟化",这是一个优化步骤,旨在通过使用静态调度加速虚拟调用,并可能内联它们。
这解释了链接器错误,因为它试图将IClass::release()
链接到可执行文件中,但无法在本地找到它。
这种"去虚拟化"行为也出现在clang上,但不太可能发生在msvc++上
部分相关建议
<引用类>如果您需要通过指向其抽象类(或抽象基类)的指针来释放对象:
如果你也在处理共享库:
std::nothrow
版本由于接口实现将驻留在库中,因此为每个您认为客户端可构造的接口导出一个工厂函数。只要确保异常不会通过客户端和库之间的间隙传播。
这样,客户机应用程序就可以在库的CRT分配的对象上使用
delete
,没有麻烦。
引用类>
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 有没有办法在不重新实现的情况下从子类中标记父级的虚拟函数 final。
- 为什么"override/final"需要放在函数声明符之后?
- 纯虚拟的final函数:在C++11中是合法的
- 是当虚拟函数立即标记为final时生成的vtable
- 派生类中的非虚函数C++名称与“final”说明符冲突
- 派生类中的final函数重载
- 类的相同成员函数可以用 c++ 中的说明符声明"override & final"吗?
- C++11 中的 "final" 关键字对函数有什么用?
- 将基类函数标记为虚函数和final函数有什么意义吗?
- 默认将类设置为“final”或给它们一个虚析构函数
- Java的final方法与c++的非虚函数
- 虚函数上final的奇怪行为