NVI(非仮想インターフェイス)とテンプレートメソッドパターンの違いは何ですか?
それらは非常に似ているように見え、基本的に同じであり、テンプレートが何らかの形でより一般的であるという点で微妙に異なることの両方を読みました。
NVI(非仮想インターフェイス)とテンプレートメソッドパターンの違いは何ですか?
それらは非常に似ているように見え、基本的に同じであり、テンプレートが何らかの形でより一般的であるという点で微妙に異なることの両方を読みました。
NVI はイディオム、Template Method はパターンです。NVI は、C++ での動的ディスパッチを使用したテンプレート メソッド パターンの実装です。テンプレート メタプログラミングを使用して C++ でテンプレート メソッドを作成し、動的ディスパッチをなくすこともできます。
パターンはイディオムよりも一般的であり、言語はパターンを実装するために異なるイディオムを使用する場合があります。
すでに述べたように、NVI は言語のカテゴリに関連するプログラミング イディオムです。契約の実施に役立つため、特に Herb Sutter によって推進されています。
ただし、実装は実際にはかなり異なる場合があります。たとえば、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
公開されたクラスにはまったくありません (プライベートでさえありません)。メモリ レイアウトは、下位互換性と上位互換性があります。バイナリ互換を実現しています。
ここでは、一度にいくつかのパターンを使用します。