C++ 虚函数上final的奇性
我遇到了一个奇怪的情况,将C++ 虚函数上final的奇性,c++,final,c++14,undefined-reference,C++,Final,C++14,Undefined Reference,我遇到了一个奇怪的情况,将final关键字添加到虚拟函数声明中,其定义位于单独的.cpp文件中。 考虑下面的例子: IClass.hpp class IClass //COM-like base interface { protected: virtual ~IClass(){} //derived classes override this public: virtual void release() final; }; dllmain.cpp(共享库) main.cpp(
final
关键字添加到虚拟函数声明中,其定义位于单独的.cpp文件中。考虑下面的例子: IClass.hpp
class IClass //COM-like base interface
{
protected:
virtual ~IClass(){} //derived classes override this
public:
virtual void release() final;
};
dllmain.cpp(共享库)
main.cpp(独立可执行)
实际上,GCC4.9.2将报告对“IClass::release()”的未定义引用。
我的目标是使
IClass::release()
不可重写,同时将其实现隐藏在游戏引擎的共享库中。有什么建议吗?对GCC使用的
final
做了一些挖掘,发现了标记为final-get的虚拟函数,这是一个优化步骤,旨在通过使用静态分派和可能的内联来加速虚拟调用
这就解释了链接器错误,因为它试图将IClass::release()
链接到可执行文件中,但在本地找不到它
这种“非虚拟化”行为也出现在clang上,但不太可能发生在MSVC上++
部分相关建议 如果您需要通过指向其抽象类(或抽象基类)的指针释放对象的方法:
如果您也在处理共享库:
std::nothrow
版本由于接口实现将驻留在库中,请为您认为客户端可构造的每个接口导出工厂函数。
只需确保异常不会通过客户端和库之间的间隙传播。
这样,客户机应用程序就可以在库的CRT分配的对象上使用
delete
,而无需麻烦
除非是纯函数,否则通常使用odr。我相信在这种情况下,链接器可以发布错误。我无法在GCC4.9.2中重现该问题。请添加如何构建程序(编译器选项等)是否从dll导出函数@0x49 I误以为它们的odr使用的是实现定义的。@dyp:dll是使用此函数构建的。主二进制文件使用相同的编译器标志,但以下链接器标志:
-static libgcc-static libstdc++-mwindows
@Yakk[basic.def.odr]/p5:“如果虚拟成员函数不是纯函数,则使用odr。”我认为是否存在链接器错误取决于实现。
#include "IClass.hpp"
...
void IClass::release()
{
delete this;
}
...
//various includes here
...
int main(int argc, char** argv)
{
/* From "IGameEngine.hpp"
class IGameEngine : public IClass
{
...
};
*/
IGameEngine* engine = factoryGameEngine();
...
engine->release();
return 0;
}