8

ライブラリで次のコードを見つけました。

class Bar {
public:
  bool foo(int i) {
   return foo_(i);
  }
private:
  virtual bool foo_(int i) = 0;
};

今、私は疑問に思っています: なぜこの間接化を使用するのでしょうか? 上記が単純な代替手段よりも優れている理由は何かありますか?

class Bar {
public:
  virtual bool foo(int i) = 0;
};
4

4 に答える 4

10

これは非仮想インターフェースイディオム(NVI)です。ハーブサッターによるそのページには、それについてかなりの詳細があります。ただし、C ++ FAQ Liteがここここで述べていることを使用して、そこで読んだ内容を調整してください。

NVIの主な利点は、インターフェイスを実装から分離することです。基本クラスは一般的なアルゴリズムを実装して世界に提示でき、そのサブクラスは仮想関数を介してアルゴリズムの詳細を実装できます。特に、前処理コードと後処理コードを追加することに後でした場合は、外部ユーザーはアルゴリズムの詳細の変更から保護されます。

明らかな欠点は、余分なコードを書かなければならないことです。また、private仮想関数は多くの人を混乱させます。多くのコーダーは、あなたがそれらをオーバーライドすることはできないと誤って考えています。ハーブサッターはバーチャルが好きなようですprivateが、私見では、C ++ FAQ Liteの推奨事項に従って、バーチャルを作成する方が実際にはより効果的protectedです。

于 2009-03-19T18:02:54.530 に答える
3

これがテンプレートパターンです。fooメソッドには、すべてのサブクラスで実行する必要のあるコードが含まれています。このように見ると、より理にかなっています。

class Bar {
public:
  bool foo(int i) {
   // Setup / initialization / error checking / input validation etc 
   // that must be done for all subclasses
   return foo_(i);
  }
private:
  virtual bool foo_(int i) = 0;
};

これは、各サブクラスの共通コードを個別に呼び出すことを忘れないようにするという代替手段よりも優れています。必然的に、誰かがサブクラスを作成しますが、共通コードを呼び出すのを忘れて、問題がいくつも発生します。

于 2009-03-19T17:58:27.273 に答える
3

これは Wolfgang Pree によって造られた Template-Hook ペア (別名 Hotspot) と呼ばれることがよくあります。

このPDFパワーポイントHTMLを参照してください。

呼び出し時に間接化を行う理由の 1 つは、メソッドの前に物事をセットアップできる/セットアップしなければならないことが多く、いくつかのクリーニングがメソッド呼び出しをポストすることです。サブクラスでは、セットアップクリーニングを行うことなく、必要な動作を提供するだけで済みます...

于 2009-03-19T17:54:16.033 に答える
0

サブクラスがfoo_?の定義を変更できるが、コンシューマーが(効率のために)静的関数を必要とした場合?または委任パターンの場合は?

于 2009-03-19T17:55:25.953 に答える