10

質問があります。以下に2つのクラスがあります。

  class Base{
      public:
          virtual void toString();       // generic implementation
  }

  class Derive : public Base{
      public:
          ( virtual ) void toString();   // specific implementation
  }

質問は:

  • クラスDeriveのサブクラスがBaseのポインターを使用してポリモフィズムを実行したい場合、括弧内のキーワードvirtualは必要ですか?

  • 答えが「いいえ」の場合、仮想を使用する場合と使用しない場合のクラスDeriveのメンバー関数toStringの違いは何ですか?

4

7 に答える 7

13

C++03§10.3/2:

仮想メンバー関数vfがクラスBaseおよびBaseから直接または間接的に派生したクラスDerivedで宣言されている場合、Base :: vfと同じ名前および同じパラメーターリストを持つメンバー関数vfが宣言され、次にDerived:: vfが宣言されます。また、仮想であり(宣言されているかどうかに関係なく)、Base::vfをオーバーライドします。

于 2010-04-19T19:33:41.697 に答える
10

そのキーワードは厳密にオプションであり、まったく違いはありません。

于 2010-04-19T18:00:45.393 に答える
7

プロパティは基本クラスから継承され、virtual入力しなくても存在すると見なされます。

于 2010-04-19T18:02:55.630 に答える
1

コンパイラは、基本クラスの「virtual」キーワードから、toStringが仮想メソッドであることをすでに認識しています。繰り返す必要はありません。

于 2010-04-19T18:03:26.827 に答える
1

かつては仮想だった関数は常に仮想です。

したがって、いずれにしても、virtualキーワードが後続のクラスで使用されない場合でも、関数/メソッドが「仮想」になること、つまりオーバーライドされることを妨げることはありません。したがって、次のガイドラインは、チーム開発の観点から役立つ可能性があります:-

  • 関数/メソッドがオーバーライドされることになっている場合は、常に「virtual」キーワードを使用してください。これは、インターフェイス/基本クラスで使用する場合に特に当てはまります。
  • 派生クラスがさらに明示的にサブクラス化されることになっている場合は、オーバーライドできるすべての関数/メソッドの「virtual」キーワードを明示的に記述します。
  • 派生クラスの関数/メソッドが再度サブクラス化されない場合は、キーワード'virtual'にコメントを付けて、関数/メソッドがオーバーライドされたことを示しますが、それを再度オーバーライドするクラスはありません。もちろん、このクラスがfinal(派生不可)にされない限り、派生クラスで誰かがオーバーライドするのを防ぐことはできませんが、メソッドがオーバーライドされることは想定されていないことを示しています。元:/*virtual*/ void someFunc();
于 2010-04-19T18:13:01.710 に答える
0

関数の派生バージョンでvirtualキーワードを指定するかどうかは、コンパイラーにとって重要ではありません。

ただし、とにかくそれを提供することをお勧めします。そうすれば、コードを見ている人なら誰でも、それが仮想関数であることがわかります。

于 2010-04-19T20:46:59.130 に答える
0

それは良いスタイルの問題であり、ユーザープログラマーは何が起こっているのかを知っています。C ++ 0xでは、[[override]]を使用して、より明示的で見やすくすることができます。[[base_check]]を使用して、[[override]]の使用を強制できます。

望まない、またはできない場合は、virtualキーワードを使用してください。

仮想toStringなしで派生し、DeriveのインスタンスをBaseにキャストして戻す場合、toString()を呼び出すと、実際にはBaseのtoString()が呼び出されます。これは、それがBaseのインスタンスであることがわかっているためです。

于 2010-04-20T00:34:35.543 に答える