両者の区別がつかなくて困っています。通常は重複しない場合、どのように違うのですか? 前提条件であるが不変条件ではないものの例は何ですか?
4 に答える
他のいくつかの回答は、「前提条件」と「不変」という用語を定義しようとしています。たとえば、ウィキペディアの方がはるかに優れていると思うので、代わりに、定義についてウィキペディアにリンクしました。いずれにせよ、質問が定義のみに関するものである場合、それはRTFMの質問であり、私は回答する代わりに、それを閉じることに投票したでしょう。
「[前提条件と不変条件] が通常重複しない場合、それらはどのように異なるのでしょうか?」
メソッドの前提条件は、個々のサブ条件の結合から形成された単一の前提条件と常に見なすことができるため、「the」前提条件について話したり推論したりすることがよくあります。
パブリック メソッドの場合、サブ前提条件の 1 つは常にクラス インバリアントであるため、重複することがよくあります。
内部 (private
およびprotected
) メソッドを検討すると、事態はさらに複雑になります。多くの場合、パブリック メソッドは、クラスの不変条件を一時的に解除してから復元することで機能します。無効なクラス不変の期間中、いくつかの内部ヘルパー メソッドを呼び出す可能性があり、それらの内部ヘルパー メソッドは、事前条件にクラス不変を含めることができません。
パブリック インターフェイスと実装の詳細を明確に区別しようとすると、事態はさらに複雑になります。Eiffel のようなDesign By Contract ( DBC ) アサーションをこれに取り残された C++に導入しようとする以前の試みです。
ただし、実際には非常にトリッキーなケースを回避し、いわばその周りを設計することができるため、実際には十分に簡単です。
「前提条件であるが不変条件ではないものの例は何ですか?」
例えば、
class Foo
{
public:
void add( Bar* p )
{
assert( p != 0 ); // Precondition unrelated to the class invariant
// ... whatever
}
};
前提条件とは、前に真でなければならないが、最中や後に必ずしも真であるとは限らないものです。名前が示すように、不変条件は、どの時点でも変化しません。たとえば、ベクトルを正規化するとします。前提条件は、現在のノルムが 0 であってはならないということです (ゼロによる除算が発生するため)。正規化の操作はベクトルのノルムを変更します。つまり、それは前提条件であり、不変条件ではありません。
短い答えはイエスです。前提条件、事後条件、および不変条件は、本質的に同じものの異なる側面です。
前提条件は、操作を完了する前の「瞬間的な」チェックです。事後条件は、操作完了後の「瞬間的な」チェックです。不変条件は、しばらく持続するチェックです。
たとえば、引数が >= 0 である必要がある平方根関数がある場合、それは操作の前に実行されるチェックであるため、前提条件です。
一方、メンバー x と y を持つクラスがあり、x > y が常に存在する場合、条件はしばらくの間 (オブジェクトの存続期間中) 持続するため、不変です。同様に、ループがあり、ループのすべての反復で何らかの条件が保持される必要がある場合、チェックがしばらく持続するため、それも不変条件です。一般に、クラス不変およびループ不変という用語は、不変のタイプを指定するために使用されます。
通常、不変条件は状態のプロパティです。たとえば、1 <= x <= 100
常にそれを主張するかもしれません。
メソッド呼び出しには前提条件が適用されます。たとえば、x
上記を含むクラスにメソッドがある場合Foo(int y, int z)
、前提条件は、関数呼び出しが有効である可能性がy < x
あります。z > 10000