C++中的松散抛出说明符

7
我遇到了这样一个错误信息:
错误:virtual CPLAT::CP_Window::~CP_Window() 的 throw specifier 更宽松
在析构函数中,我以前从未听说过这种情况。一些谷歌搜索结果显示这可能是GCC 4的问题,但我不确定如何解决,因为我需要使用GCC 4来构建通用二进制文件。
我的环境:OS X 10.6、XCode 3.2.2、使用GCC 4构建通用二进制文件。
问题出在哪里?
2个回答

12
我假设CPLAT有一个基类?我还猜测您没有在CPLAT的析构函数上放置throw声明符?
您可以在函数签名的末尾放置 throw(X)(其中X是逗号分隔的异常列表),以指示它允许抛出哪些异常。如果将 throw() 作为 throw 声明符,则表示该函数不会抛出任何异常。通常对析构函数这样做非常常见,因为您永远不希望析构函数抛出异常。
覆盖具有 throw 声明符的函数的类不能具有比被覆盖的函数更宽松的 throw 声明符(列出更多异常),因为这将表明派生类函数可能会违反基类函数的 throw 声明符。没有 throw 声明符意味着该函数可以抛出任何异常,所以它是最宽松的。
很可能,您需要在CPLAT的析构函数的函数签名末尾添加 throw()。
编辑:顺便说一句,您可能不希望在不确切知道自己想要的情况下使用 throw 声明符(除了在析构函数中使用 throw())。与 Java 的已检查异常不同,它们不是在编译时捕获,而是在运行时终止程序,如果违反,则最好不使用它们,除非您知道自己在做什么。

2
我的stl实现将std::exception的析构函数声明为~exception() throw();。现在,如果我将其用作自己异常的基类,即使在那个析构函数中没有任何操作,我也必须在每个派生类中声明一个析构函数,因为如果我不这样做,gcc会报错。有没有办法避免这种冗余的声明? - Moritz Both
2
据我所知,如果没有其他原因,那是因为它在技术上不是冗余的。如果您不定义析构函数,则会得到一个没有抛出说明符的析构函数。因此,它具有错误的函数签名。您必须通过使用空的抛出说明符throw()来定义它的正确函数签名。如果编译器可以自动完成这项工作,那就太好了,但显然它并不那么聪明。 - Jonathan M Davis

5

截至2012年2月14日,现在排名第一的结果是这篇帖子。;-) - dkaranovich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接