Coplienの封筒/レターパターンは、(彼のにブック高度なC++プログラミングスタイルとイディオムを読まなければならない)、これを行うための古典的な方法です。
簡単に言うと、エンベロープとレターは、すべてのサブクラスのパブリックインターフェイスを定義する抽象基本クラス/インターフェイスのサブクラスです。
封筒は、文字を保持しています(真のタイプを隠しています)。
さまざまなレタークラスには、抽象クラスのパブリックインターフェイスの実装が異なります。
エンベロープには実際の実装はありません。その手紙のほんの一部(代表者)です。これは、抽象基本クラスへのポインタを保持し、それを具体的なレタークラスインスタンスでポイントします。インプリメンテーションを変更する必要があるので、toへのLetterサブクラスのポインタのタイプが変更されます。
ユーザーはエンベロープへの参照のみがあるため、エンベロープの動作が変更される点を除いて、この変更は表示されません。
Coplienの例は、文字のためであり、変更を引き起こすエンベロープではないため、特にきれいです。
1つの例は、Numberクラス階層です。抽象的なベースは、すべての数値に対するある種の演算、例えば加算を宣言します。 IntegerとComplexは具体的なサブクラスの例です。
IntegerとIntegerを追加するとIntegerが生成されますが、IntergetとComplexを追加するとComplexになります。
はここで封筒を追加するための次のようになります。クライアントのポインタで今
public class Number {
Number* add(const Number* const n) ; // abstract, deriveds override
}
public class Envelope : public Number {
private Number* letter;
...
Number* add(const Number& rhs) { // add a number to this
// if letter and rhs are both Integers, letter->add returns an Integer
// if letter is a a Complex, or rhs is, what comes back is a Complex
//
letter = letter->add(rhs)) ;
return this;
}
}
変化したことがない、と彼らはこれまでにエンベロープを保持しているかを知る必要がありません。ここでは、クライアントコードです:彼の本で
int main() {
// makeInteger news up the Envelope, and returns a pointer to it
Number* i = makeInteger(1) ;
// makeComplex is similar, both return Envelopes.
Number* c = makeComplex(1, 1) ;
// add c to i
i->add(c) ;
// to this code, i is now, for all intents and purposes, a Complex!
// even though i still points to the same Envelope, because
// the envelope internally points to a Complex.
}
は、Coplienはより深くに入る - 、及び糖衣構文を追加します - あなたは、addメソッドは、何らかの形のマルチ派遣を必要とすることに注意しましょう。しかし、これはの要点で、「ランタイムポリモーフィズム」と呼ばれるものをどのように得ることができます。
あなたは何をしようとしているのですか?たぶんあなたは多型について考えるべきです。 –
何が必要ですか?質問を展開してください。 – bayda
質問を展開する必要があります。特定の状況下で行うことができるものよりもいくつかあります... –