派生自库中的std::exception:仅头文件解决方案是否适用于捕获异常



在我们的跨平台开源库中,我们从std::exception派生,以便定义可以在库代码和用户代码中捕获的自定义异常。我看到这实际上是一个推荐的过程,但在Visual Studio 2015中(或者更确切地说,伴随的新MSVC版本?)在实现类中抛出警告(警告C4275) -也请参阅这里:如何导出从std::runtime_error派生的类?

当然,我们可以忽略这个错误,但我觉得这是错误的。

出现警告的原因,与旧的Visual Studio版本相比,似乎是std::异常曾经在旧的MSVC版本中被导出,但同时不再被导出。无论哪种情况,我都觉得以将其编译到库中的形式继续讨论这个问题从来都不是"正确的方式"。

从我在回答中读到的,一个更好的方法是"内联"类,因为导出基类(std::exception)可能会导致更多的复杂性。如果我理解正确的话,这里的"内联"意味着不使用"内联"关键字,而是将定义移动到标题中,而不是导出它。这是正确的吗?

假设这是什么意思:我的问题是,如果编译的库抛出异常,这是定义在它的头文件之一,将允许在动态链接该库的可执行文件中正确捕获异常。但是如果编译器是不同的呢?运行时类型信息(RTTI)似乎与此相关,因此即使使用不同的编译器版本或甚至不同的编译器,也能保证以上述方式工作吗?如果这不起作用,如何以"正确"的方式解决这个问题?

引自问题中链接的帖子中的Microsoft Connect问题;

…将STL类型放在DLL的接口中会迫使您按照STL的规则来操作(具体来说,您不能混合使用不同的VC主要版本,并且您的IDL设置必须匹配)。然而,有一种变通方法。C4251本质上是噪声,可以静音…

混合编译器版本和选项可能(在某些时候可能会)导致问题和不可预测的应用程序行为。所以,没有保证它会起作用,很可能相反,它不会起作用。

当使用上面提到的内联技术(即一个头文件实现),并确保设置和编译器在项目之间是一致的,允许在给定的dll导出约束下工作。

考虑到它是一个开源项目,它可以很容易地为客户端环境构建,所以上面提到的任何技术都应该是合适的,因为客户端将能够在给定编译器和选项的情况下构建代码。

相关内容

最新更新