26

クラスBに仮想関数foo()があり、Bの派生クラスの1つであるクラスDでわずかに異なる動作が必要であるとします。オーバーライド関数D :: foo()を作成し、B :: foo( )そこから、特別な場合の治療の後?このような:

void D::foo()
{
  if (/*something*/)
     // do something
  else
     B::foo();
}

私はそれがうまくいくかどうか尋ねていません、私はそれがうまくいくことを知っています。良いOODの観点からそれが正しいかどうか知りたいです。

4

7 に答える 7

22

これは完全に良いです。実際、一部の操作を実行する標準的な方法は、基本クラスのメソッドを呼び出してから、何でも (またはその逆) を実行することです。ここを考えてoperator=います。コンストラクターも、初期化リストで少し偽装されていても、通常はそのように機能します。

于 2009-05-13T10:09:17.780 に答える
6

はい、リスコフの置換原則に違反していない限り、まったく問題ありません。

于 2009-05-13T10:08:25.613 に答える
4

はい、そうです。

于 2009-05-13T10:07:21.373 に答える
1

GUIフレームワークがこれを使用して、エラーを通知する/例外をスローする/汎用値を返すコードを含む基本クラスのデフォルト実装にフォールバックするのを見てきました。

于 2009-05-13T10:07:36.940 に答える
1

大丈夫です。あなたが与えた構文は、ポリモーフィズムを一時的にオフにするためにも使用できます。つまり、obj->B::foo() メソッドを呼び出すと、foo() が仮想であるかどうか、および obj が B のインスタンスであるかどうかに関係なく、クラス B から選択されます。かどうか (ただし、B を拡張するクラスのインスタンスである必要があります)。

于 2009-05-13T10:19:21.820 に答える
0

はい、そうです。これは、コンパイラがコンストラクタとデストラクタを生成するたびに行うことです。たとえば、母親のものを呼び出します。私は自分のコードでその「トリック」に頼ることがよくあります。

于 2009-05-13T10:10:40.883 に答える
0

ベースの実装を呼び出すことは問題ありませんが、条件付きで実行すると、他の回答で提案されていることとは対照的に、コンストラクターのセマンティックから離れます。

次の 2 つの方法で、脆弱な基本クラスの問題が発生する可能性があります。

  • 階層全体に共通の動作を提供すると仮定するB::foo()(つまり、メソッドが常に呼び出されるとは限らない)
  • // do something実際に何をするかによって厄介な問題!

完全を期すために、対称設計アプローチについて言及しましょう:テンプレートパターン(特定のサブパーツを呼び出す基本実装)

于 2013-12-17T19:53:49.323 に答える