17 March 2022

C++ 核心指南目录

I.5: State preconditions (if any)

理由

函数参数的实际意义会限制函数调用者的使用。

例子

double sqrt(double x);

此处 x 必须是非负的。类型系统不能很好很自然的表达这种属性,因此我们要通过其他途径表达。比如,通过代码注释:

double sqrt(double x); // x 须为非负

有些前提条件可以用断言语句表达,比如:

#include <gsl/gsl_assert>
double sqrt(double x) { Expects(x >= 0); /* ... */ }
int main()
{
    sqrt(-1.0);
    return 0;
}
terminate called without an active exception

理想的情况,Expects(x >= 0)应该是sqrt()接口的一部分。但是很难实现,目前,我们暂时可以将断言放在函数体定义内。

注意

尽量选择以正式的规格需求表达,如Expects(p);如果不可行,就在注释中写:

// the sequence [p:q) is ordered using <.
// 序列 [p:q) 以 < 排序

注意

大部分的成员函数有一个隐含的前置条件,即类中数据满足某个不变式。这个不变式条件是通过构造函数建立的。必须在每次成员函数调用之后依然保证这个不变式约束条件。当然,我们无需在每个成员函数中明确指出这个不变式约束条件。