不变量和 noexcept

Invariants and noexcept

在C++中,如果一个方法可能只是因为class的不变量没有被维护而抛出,我应该把它标记为noexcept吗?

例如,一个列表有一个指向 link 的指针,它应该是 nullptr 或正确的指针,并且有一个方法取消引用该指针。它会阻止使用 noexcept 吗?

如果函数抛出异常报告任何问题,则不应声明它 noexcept。它实际上违反了它承诺满足的合同。

无论是否抛出异常,对象保持不变也是一种很好的做法。通常的做法是所有构造函数都建立一个不变量,所有其他成员函数都保持该不变量,直到对象被销毁(并调用析构函数)。

如果一个函数取消引用 nullptr,它的行为是未定义的。不需要抛出异常。

如果一个方法在取消引用空指针时会抛出异常,则不应标记为 noexcept。如果你真的希望它是 noexcept,你应该在取消引用之前测试指向 null 的指针(和 return 一个特殊值)。例如

if (pt == NULL) return NULL;
// do use *pt or pt->xxx

如果一个函数可以通过异常退出,你不应该标记它 nothrow; nothrow 保证它 永远不会 通过 例外。至少有几个功能是必不可少的 如果您想编写异常安全代码,则永远不要抛出(我的意思是永远不要)。

如果无法维护 class 不变量,则不应抛出 例外;您所能做的就是中止该过程。别 将其与无法建立不变量的构造函数混淆, 然而;可以抛出,因为不会有任何物体 之后不符合不变量。另外,在某些 情况下,定义一组较弱的不变量是有效的 投掷。说只是足以保证对象可以安全 毁了。这取决于应用程序(以及设计如何处理 例外)。但是这样的函数不能声明nothrow.

关于您的具体示例:如果不变量是 正确的指针或空指针,没有办法测试它并得到一个 反正例外。如果指针无效(不指向有效 类型的对象,并且不为空),那么你有未定义的行为。 任何事情都可能发生,在真实的系统上,如果你 取消引用指针。