:GoFは、C++テンプレートメソッドパターンの実装で保護された(プライベートではなく)仮想メソッドを使用することをアドバイスしているのはなぜですか? Template Methodパターンの四人組から
三の実装上の問題は注目に値する:C++のアクセス制御を使用して
- 。 C++では、テンプレートメソッドが呼び出すプリミティブ操作は、保護されたメンバーとして宣言できます。これにより、 はテンプレートメソッドによってのみ呼び出されることが保証されます。上書きされなければならないプリミティブ操作 は純粋仮想と宣言されます。テンプレートメソッド 自体を上書きしないでください。したがって、テンプレート メソッドを非仮想メンバ関数にすることができます。
"これにより、テンプレートメソッドによってのみ呼び出されることが保証されます。"それは本当ですか?プリミティブメソッド(例えば、いくつかが純粋な仮想ではなく仮想である場合)は、派生クラスから呼び出すこともできます。プリミティブメソッドをプライベート宣言するだけで、テンプレートメソッドによって呼び出されることが保証されていることは確かではありませんか?プライベート仮想プリミティブメソッドは、サブクラスで実装(または再実装)され、スーパークラスのテンプレートメソッドで定義されたアルゴリズム内で必要とされる特殊な動作を提供することができます。
ハーブサッターから見る "バーチャリティ":
http://www.gotw.ca/publications/mill18.htm
彼は述べている:
ガイドライン#2:仮想関数をプライベートにすることを好むに。 ガイドライン#3:派生クラスが 仮想関数の基本実装を呼び出す必要がある場合のみ、仮想関数を保護します。
派生クラスが仮想関数の基本クラスの実装を呼び出すためのGoFテンプレートメソッドパターンには何も必要ありません。なぜGang of Fourはこれらの関数をプライベートではなく保護することを推奨しますか?
歴史的な考え方は多かれ少なかれ、1995年に私は、ほとんどのC++プログラマが私的な機能を無効にすることさえできないと考えています。(そして 'std :: streambuf'の仮想関数はプライベートではなく、保護されています。)今日でも、このような関数には' private'ではなく 'protected'を優先する人がいると私は思っています。彼らは確かに派生クラスに知られていなければなりません。そして、それらの人々のために、「私的」とは、コンパイラではないにしても、少なくとも人間の読者にとっては私的な意味です。 –
@James私はそれを証明することができます...最近まで私はこれが合法であることに気付かず、最初は非常に直感的でした... –
ありがとう。私はこれが答えだと思っていましたが、Stephen DewhurstのC++ Common Knowledge(2005)を手にして質問をしましたが、私が紛失していた保護された/私的な議論に何かがあるという疑いが生じました。テンプレートメソッドの章では、保護された仮想関数を呼び出すために "一般的に"実装されていることを記述しています。この関数は、コード例で使用します。それ以外の場合、テンプレートメソッドによって呼び出されるプリミティブ関数について、プライベートとプロテクトの問題は何も言及していません。 –