14.9 先决条件
最后更新于:2022-04-01 06:24:47
通常当你写函数时会对接收的参数做了隐含的假设。如果这些假设成立,程序没有问题;如果假设不成立,你的程序可能就会崩溃了。
为了让你的程序更为健壮,将你的假设明确,以程序文档的方式写下来或写代码来进行检查。
比如我们观察calculateCartesian方法。是否存在对当前对象进行了假设呢?没错,我们假设极坐标系的标志量已经设置了并且mag和theta的值是有效的。如果假设不成立,那么这个函数的结果无意义。
一种做法是对函数添加注释说明先决条件以警告他人。
~~~
void Complex::calculateCartesian ()
// 先决条件:当前对象包含有效的极坐标值,其极坐标标志量已设定。
// 后置条件:当前对象包含有效的笛卡尔坐标系和极坐标系的值,两个标志量皆已设置。
{
real = mag * cos (theta);
imag = mag * sin (theta);
cartesian = true;
}
~~~
同时,我添加了后置条件,即我们认为函数执行完毕后为真的事情。
这些注释对于阅读你代码的人很有用,但更好的办法是通过代码来检查先决条件,并输出合适的错误信息:
~~~
void Complex::calculateCartesian ()
{
if (polar == false) {
cout << "calculateCartesian failed because the polar representation is invalid" << endl;
exit (1);
}
real = mag * cos (theta);
imag = mag * sin (theta);
cartesian = true;
}
~~~
exit函数会使程序很快的退出执行。返回值是一个错误码以告诉系统(或该程序执行者)某些错误发生。
这种错误检测方式很是常见,于是C++提供了一个内置函数来检查先决条件并打印错误信息。如果你包含了assert.h头文件,你可以使用一个以布尔值或条件表达式为参数的assert函数。只要参数为真,assert函数就啥也不做。如果参数为假,assert打印一个错误信息并退出,用法如下:
~~~
void Complex::calculateCartesian ()
{
assert (polar);
real = mag * cos (theta);
imag = mag * sin (theta);
cartesian = true;
assert (polar && cartesian);
}
~~~
第一句assert检查先决条件(事实上只是一部分先决条件),第二句assert检查后置条件。
在我的开发环境中,当一个断言失败时会得到以下信息:
~~~
Complex.cpp:63: void Complex::calculatePolar(): Assertion ‘cartesian’ failed.
Abort
~~~
信息中会有许多内容可以帮助我跟踪错误,包括文件名和断言失败的出错行,断言语句的内容和所在函数名。