据我所知,在DbC方法中,前置条件和后置条件附加到函数中。
我想知道的是,这是否适用于会员功能。
例如,假设我在每个公共函数末尾的开头使用不变量,成员函数将如下所示:
编辑:(清理我的例子)
void Charcoal::LightOnFire() {
invariant();
in_LightOnFire();
StartBurning();
m_Status = STATUS_BURNING;
m_Color = 0xCCCCCC;
return; // last return in body
out_LightOnFire();
invariant();
}
inline void Charcoal::in_LightOnFire() {
#ifndef _RELEASE_
assert (m_Status == STATUS_UNLIT);
assert (m_OnTheGrill == true);
assert (m_DousedInLighterFluid == true);
#endif
}
inline void Charcoal::out_LightOnFire() {
#ifndef _RELEASE_
assert(m_Status == STATUS_BURNING);
assert(m_Color == 0xCCCCCC);
#endif
}
// class invariant
inline void Charcoal::invariant() {
assert(m_Status == STATUS_UNLIT || m_Status == STATUS_BURNING || m_Status == STATUS_ASHY);
assert(m_Color == 0x000000 || m_Color == 0xCCCCCC || m_Color == 0xEEEEEE);
}
是否可以仅使用全局/泛型函数的前提条件和后置条件,只使用类中的不变量?
这看起来有点矫枉过正,但也许我的榜样很糟糕。
编辑:
后置条件不仅仅是检查不变量的子集吗?
在上面,我遵循http://www.digitalmars.com/ctg/contract.html的指示,指出:“在类构造函数完成时,在类析构函数的开始,在运行公共成员之前,以及在运行公共成员之后检查不变量。公共职能完成。“
感谢。
答案 0 :(得分:5)
将类中的合同限制为不变量并非最佳。
前提条件和后置条件不仅仅是不变量的一个子集。
不变量,前提条件和后置条件具有非常不同的作用。
不变量确认对象的内部一致性。它们应该在构造函数的末尾以及每次方法调用之前和之后有效。
前置条件是检查对象和参数的状态是否适合执行方法。前提条件是不变量的补充。它们包括对参数的检查(更强的检查类型本身,即非null,> 0,...等),但也可以检查对象的内部状态(即调用file.write(“) hello“)只有在file.is_rw和file.is_open为真时才是有效的调用。”
后期条件正在使该方法满足其义务后置条件也是不变量的补充。当然,对象的状态必须在方法执行后保持一致,但后置条件检查是否执行了预期的操作(即list.add(i)应该具有list.has(i)为真的结果和list.count = old list.count + 1)。
答案 1 :(得分:4)
是
C类的不变是其所有实例(对象)的公共属性。当且仅当对象处于语义有效状态时,不变量的计算结果为真。
电梯的不变量可能包含ASSERT(IsStopped() || Door.IsClosed())
等信息,因为电梯处于与停止(例如,上升)不同的状态并且门打开时无效。
相比之下,MoveTo(int flat)
等成员函数可能会将CurrentFlat()==flat
作为后置条件;因为在调用MoveTo(6)后,当前平面为6.同样,它可能有IsStopped()
作为前提条件,因为(取决于设计)你不能调用函数MoveTo如果电梯已经移动了首先,您必须查询其状态,确保它已停止,然后调用该函数。
当然,我可能完全过分简化了电梯的运作方式。
无论如何,一般来说,先决条件和后置条件作为不变条件是没有意义的;电梯不需要在6楼处于有效状态。
可在此处找到更简洁的示例:Interception and Attributes: A Design-By-Contract Sample by Sasha Goldshtein。
答案 2 :(得分:2)
嗯,不变量的意思是它始终描述了对象的真实。在这种情况下,烤架上是否有东西(两者之间没有任何东西)。它们通常描述对象整个状态的属性。
前置条件和后置条件描述了在方法执行之前就已经存在的事情,以及之后,并且将关注仅仅应该被方法触及的状态。据推测,这与对象的状态不同。前后条件可能被认为是描述方法的足迹 - 正是它所需要的,只是它触及的内容。
所以,对于具体的问题,这些想法做了不同的事情,所以你可能都想要两者。你当然不能只使用不变量而不是前后条件 - 在这种情况下,对象不变量的一部分是“有什么东西在烤架上”,但是lightOnFire的前提条件是需要知道物品在烤架上。你永远无法从对象不变量中推断出这一点。确实,从前置条件和后置条件以及已知的开始状态,您可以(假设对象结构只能通过方法变化,前后条件描述所有环境变化),推断对象不变。然而,这可能很复杂,当你用“语言”陈述事物时,更容易提供两者。
当然,在声明布尔项的变体中执行true或false是有点无意义的 - 类型系统确保了。