C ++:NVIとテンプレートメソッドパターンの違いは?
-
28-09-2019 - |
質問
NVIの違いは何ですか( 非仮想的なインターフェイス ) そしてその テンプレートメソッド パターン?
彼らは非常に似ているようで、私は基本的に同じであり、テンプレートが何らかの形でより一般的であることが微妙に異なることを読んだことがあります。
解決
NVIはイディオムであり、テンプレートメソッドはパターンです。 NVIは、C ++の動的ディスパッチを使用したテンプレートメソッドパターンの実装です。また、テンプレートメタプログラミングを使用してC ++でテンプレートメソッドを作成して、動的ディスパッチを排除することもできます。
パターンはイディオムよりも一般的であり、言語は異なるイディオムを使用してパターンを実装する場合があります。
他のヒント
述べたように、NVIは言語のカテゴリに関連するプログラムのイディオムです。それはとりわけハーブ・サッターによって促進されています。なぜなら、それは契約の実施に役立つからです。
- クラスの不変
- 関数契約(渡されたパラメーターを介したアサーションと生成された返品値)
- 繰り返し操作(ロギングなど)
- 生成された例外を制御する(しかし悪い考え;))
ただし、実装は実際にはかなり異なる場合があります。たとえば、NVI実装の別の例は、PIMPLと組み合わせることです。
class FooImpl;
class Foo
{
public:
enum type { Type1, Type2 };
Foo(type t, int i, int j);
int GetResult() const;
private:
FooImpl* mImpl;
};
そして実装のために:
struct FooImpl
{
virtual ~FooImpl();
virtual int GetResult() const;
};
class FooType1: public FooImpl
{
public:
FooType1(int i, int j);
virtual int GetResult() const;
private:
/// ...
};
私はいつもそれがより良いポイントを伝えていることを発見しました。あなたはそれを理解しましたか?
主なポイントはそれです virtual
実装の詳細です。インターフェイスに実装の詳細を公開することは、それらを変更したいと思うかもしれないので、悪い考えです。
さらに、実装の詳細は、バイナリの互換性を台無しにする傾向があります。たとえば、新しいものを追加します virtual
クラスのメソッドは、仮想テーブルのレイアウト(共通実装技術)を変更し、バイナリの互換性を失敗させる場合があります。 GCCでは、互換性を維持したい場合は、(仮想の中で)最後に追加することを確認する必要があります。
上記のNVI + PIMPLの組み合わせを使用することにより、 virtual
露出したクラスでは(プライベートではありません)。メモリレイアウトは、後方および前方に互換性があります。バイナリの互換性を実現しています。
ここでは、一度にいくつかのパターンを使用します。
- テンプレートメソッド
- 戦略(ポインターを自由に交換できるので)
- 工場(どの実装を取得するかを決定するため)