我很难区分这两者。如果它们通常不重叠,它们有何不同?什么是先决条件但不是不变量的示例?
4 回答
其他一些答案试图定义术语“前提条件”和“不变”。我认为例如 Wikipedia 在这方面做得更好,所以我只是链接到 Wikipedia 以获取定义。无论如何,如果问题只是关于定义,那么这将是一个RTFM问题,我会投票关闭它,而不是回答。
“如果[前提条件和不变量]通常不重叠,它们有何不同?”
一个方法的前置条件总是可以看作是由各个子条件组合而成的单一前置条件,因此我们经常说和推理“the”前置条件。
对于公共方法,子前提条件之一始终是类 invariant,所以是的,经常存在重叠。
考虑内部 (private
和protected
) 方法时,事情变得更加棘手。公共方法通常通过暂时破坏类不变量然后恢复它来工作。在类不变量无效期间,它可能会调用一些内部辅助方法,而这些内部辅助方法不能很好地将类不变量包含在其前置条件中。
当人们试图清楚地区分公共接口和实现细节时,事情变得更加棘手,而之前试图将类似 Eiffel 的契约式设计( DBC ) 断言引入 C++ 的尝试在此问题上搁浅。
不过,实践中很容易,因为对于实践中的人来说,可以避免非常棘手的情况,可以说是围绕它进行设计。
“什么是先决条件但不是不变量的例子?”
例如,
class Foo
{
public:
void add( Bar* p )
{
assert( p != 0 ); // Precondition unrelated to the class invariant
// ... whatever
}
};
先决条件只是之前必须为真但不一定在期间或之后为真的东西。顾名思义,不变量在任何时间点都不会改变。例如,假设我想规范化一个向量。一个先决条件可能是它的当前规范不能为 0(因为 I 会导致除以零)。归一化的操作将改变向量的范数,这意味着它将是一个先决条件而不是一个不变量。
不变量通常是您的状态的某些属性。例如,您可能1 <= x <= 100
总是断言。
前置条件适用于方法调用。例如,如果包含x
上面的类有一个方法Foo(int y, int z)
,则前提条件可能是y < x
并且z > 10000
函数调用有效。
简短的回答是肯定的。前置条件、后置条件和不变量本质上是同一事物的不同方面。
前提条件是完成操作之前的“即时”检查。后置条件是完成操作后的“即时”检查。不变量是持续一段时间的检查。
例如,如果您有一个平方根函数,它要求其参数 >= 0,这是一个先决条件,因为它是在操作之前进行的检查。
另一方面,如果您有一个具有成员 x 和 y 的类,使得 x > y 在任何时候,这是一个不变量,因为条件会持续一段时间(在对象的生命周期内)。同样,如果您有一个循环并且某些条件必须在循环的每次迭代中保持不变,那么这也是一个不变量,因为检查会持续一段时间。通常,术语类不变量和循环不变量将用于指定不变量的类型。