web-dev-qa-db-ja.com

C ++での再定義とオーバーライド

派生クラスでの関数の再定義とオーバーライドの違いについて混乱しています。

私は知っています-C++では、再定義された関数は静的にバインドされ、オーバーライドされた関数は動的にバインドされます。また、仮想関数がオーバーライドされ、非仮想関数が再定義されます。

派生クラスが基本クラスのメソッドを「再定義」すると、その再定義と見なされます。ただし、派生クラスが仮想の場合、再定義は行われず、オーバーライドされます。だから私はルールのロジスティクスを理解していますが、最終的な収益を理解していません。

以下の例では、関数SetScoreが再定義されています。ただし、基本クラスでsetScore関数を仮想化すると(Wordに仮想を追加することにより)、派生クラスのsetScoreがオーバーライドされます。一番下の行を理解していない-違いは何ですか。 setScore?

基本クラス:

class GradedActivity
{
protected:
   char letter;            // To hold the letter grade
   double score;           // To hold the numeric score
   void determineGrade();  // Determines the letter grade
public:
   // Default constructor
   GradedActivity()
  { letter = ' '; score = 0.0; }

 // Mutator function
   void setScore(double s) 
      { score = s;
        determineGrade();}

   // Accessor functions
   double getScore() const
      { return score; }

       char getLetterGrade() const
      { return letter; }
};

派生クラス:

class CurvedActivity : public GradedActivity
{
protected:
   double rawScore;     // Unadjusted score
   double percentage;   // Curve percentage
public:
   // Default constructor
   CurvedActivity() : GradedActivity()
      { rawScore = 0.0; percentage = 0.0; }

   // Mutator functions
   void setScore(double s) 
      { rawScore = s;
        GradedActivity::setScore(rawScore * percentage); }

   void setPercentage(double c)
      { percentage = c; }

   // Accessor funtions
   double getPercentage() const
      { return percentage; }

   double getRawScore() const
      { return rawScore; }
};

これがメインです:

   // Define a CurvedActivity object.
   CurvedActivity exam;

   ... 

   // Send the values to the exam object.
   exam.setPercentage(percentage);
   exam.setScore(numericScore);
12
YelizavetaYR

基本的な違いは次のとおりです。

overloaded関数は、1つ以上の他の関数と名前を共有する関数ですが、パラメーターリストが異なります。コンパイラーは、使用される引数に基づいて必要な関数を選択します。

overridden関数は、祖先クラスの仮想関数とは異なる定義を持つ子孫クラスのメソッドです。コンパイラーは、関数の呼び出しに使用されているオブジェクトのタイプに基づいて、必要な関数を選択します。

redefined関数は、祖先クラスの非仮想関数とは異なる定義を持つ子孫クラスのメソッドです。これを行わないでください。メソッドは仮想ではないため、コンパイラーは、オブジェクトの実際のタイプではなく、静的なオブジェクト参照のタイプに基づいて、呼び出す関数を選択します。

  • 静的型検査は、型検査がコンパイル時に行われることを意味します。その場合、実行時に型情報は使用されません。

  • 動的型チェックは、実行時に型情報が使用されるときに発生します。 C++は、RTTI(ランタイム型情報)と呼ばれるメカニズムを使用してこれを実装します。 RTTIが使用される最も一般的な例は、多様型のダウンキャストを可能にするdynamic_cast演算子です。

19
Lawrence Aiello