さらに、比較チャートを使用して、オーバーロードとオーバーライドの違いを調べます。
比較表:
比較基準 | 過負荷 | オーバーライド |
---|---|---|
プロトタイプ | プロトタイプは、パラメータの数や種類が異なると異なります。 | プロトタイプのすべての側面は同じでなければなりません。 |
キーワード | オーバーロード中にキーワードは適用されませんでした。 | オーバーライドされる機能の前には、基本クラスでキーワード「virtual」が付きます。 |
識別因子 | 呼び出される関数のバージョンを決定するパラメーターの数またはタイプが異なります。 | どのクラスの関数がポインタによって呼び出されているかは、どのクラスのオブジェクトのアドレスがそのポインタに割り当てられているかによって決まります。 |
パターンを定義する | 関数は同じ名前で再定義されていますが、パラメータの数と型が異なります。 | 関数が定義され、その前にメインクラスのキーワード「virtual」が続き、派生クラスがoutキーワードで再定義されています。 |
達成の時 | 時間をコンパイルします。 | 実行時間 |
コンストラクタ/仮想関数 | コンストラクタは過負荷になる可能性があります。 | 仮想機能は無効にすることができます。 |
デストラクタ | デストラクタはオーバーロードできません。 | デストラクタはオーバーライドすることができます。 |
製本 | 積み過ぎは早い結合を達成する。 | オーバーライドは遅延バインディングを意味します。 |
過負荷の定義
コンパイル時ポリモーフィズムは「オーバーロード」と呼ばれます。 多重定義は多態性の概念から生成されるため、「複数のメソッドに共通のインタフェース」を提供します。 つまり、関数がオーバーロードされている場合、再定義されている間は同じ関数名が含まれています。
オーバーロードされた関数は「パラメータの数や種類」が異なるという点で異なり、あるオーバーロードされた関数を別のものと区別します。 このようにして、コンパイラーはどのオーバーロード関数が呼び出されているかを認識します。 最も一般的なオーバーロード関数は 'コンストラクタ'です。 「コピーコンストラクター」は一種の「コンストラクターオーバーロード」です。
C ++でのオーバーロードの実装
クラスオーバーロード{int a、b;} public:int load(int x){//最初のload()関数a = x; を返します。 int load(int x、int y){// 2番目のload()関数a = x;} b = y。 a * bを返します。 ;}}; int main(){オーバーロードO1; O1.load(20)。 //最初のload()関数呼び出しO1.load(20, 40); // 2番目のload()関数呼び出し}
ここでクラスオーバーロードの関数load()はオーバーロードされました。 クラスの2つのオーバーロードされた関数は、最初のload()関数が単一の整数パラメータのみを受け入れるのに対して、2番目のload()関数は2つの整数パラメータを受け入れるという方法で区別できます。 クラスoverloadのオブジェクトが単一のパラメータでload()関数を呼び出すと、最初にload()関数が呼び出されます。 オブジェクトが2つのパラメータを渡してload()関数を呼び出すと、2番目のload()関数が呼び出されます。
オーバーライドの定義
実行時に達成される多態性は「オーバーライド」と呼ばれます。 それは '継承'と '仮想関数'を使って達成されます。 オーバーライドされる関数は、基本クラスではキーワード 'virtual'が先行し、キーワードなしで派生クラスで再定義されます。
オーバーライドの際に覚えておくべき最も重要なことの1つは、オーバーライドされた関数のプロトタイプは、派生クラスがそれを再定義している間に変更してはいけないということです。 オーバーライドされた関数に呼び出しが与えられると、C ++は、その関数呼び出しが行われる「ポインターが指すオブジェクトのタイプ」に基づいて、呼び出される関数のバージョンを判別します。
C ++でのオーバーライドの実装
class base {public:virtual void funct(){//基本クラスの仮想関数cout << "これは基本クラスのfunct()です"; ;}}; class derived1:public base {public:void funct(){// derived1で再定義された基本クラスの仮想関数class cout << "これはderived1クラスのfunct()です。 ;}}; クラスderived2:public base {public:void funct(){// derived2クラスのcoutで再定義された基本クラスの仮想関数funct(); // derived1クラスのfunct()を呼び出す。 * p =&d2; p - > funct(); // derived2クラスのfunct()を呼び出す。 0を返します。 }
ここには、2つの派生クラスによって公的に継承されている単一の基本クラスがあります。 仮想関数は、キーワード 'virtual'を使用して基本クラス内で定義され、それは、キーワードなしの両方の派生クラスによって再定義されます。 main()では、基本クラスはポインタ変数 'p'とオブジェクト 'b'を作成します。 'derived 1'クラスはオブジェクトd 1を作成し、derived 2クラスはオブジェクトd 2 'を作成します。
さて、最初に基本クラスのオブジェクト 'b'のアドレスが基本クラス 'p'のポインタに割り当てられます。 'p'は関数funct()を呼び出すので、基本クラスの関数が呼び出されます。 次にderived1クラスのオブジェクト 'd1'のアドレスがポインタ 'p'に割り当てられ、やはりそれはfunct()への呼び出しを与えます。 ここではderived1クラスの関数funct()が実行されます。 最後に、ポインタ 'p'はderived2クラスのオブジェクトに代入されています。 それから 'p'はderived2クラスの関数func()を実行する関数funct()を呼び出します。
derived1 / derived2クラスがfunct()を再定義しなかった場合、仮想関数は '階層的'であるため、基本クラスのfunct()が呼び出されたはずです。
オーバーロードとオーバーライドの主な違い
- オーバーロードされている関数のプロトタイプは、オーバーロードされている関数に渡されるパラメーターのタイプと数のために異なります。 一方、オーバーライドされた関数のプロトタイプは変更されません。オーバーライドされた関数は、それが属するクラスごとに異なるタイプのアクションを実行するが、パラメーターのタイプと数は同じであるためです。
- オーバーロードされた関数名の前にはキーワードはありませんが、オーバーライドされた関数の名前の前には基底クラス内では "Virtual"というキーワードだけがあります。
- どのオーバーロード関数が呼び出されるかは、その関数に渡されるパラメーターのタイプまたは番号によって異なります。 どのクラスのオーバーライドされた関数は、どのクラスのオブジェクトアドレスが、その関数を呼び出したポインタに割り当てられているかによって異なります。
- どのオーバーロードされた関数が呼び出されるべきかは、コンパイル時に解決されます。 呼び出されるオーバーライドされた関数は実行時に解決されます。
- コンストラクタはオーバーロードすることができますが、オーバーライドすることはできません。
- デストラクタはオーバーロードできませんが、オーバーライドできます。
- オーバーロードは、どのオーバーロード関数が呼び出されるかがコンパイル時に解決されるため、早期バインディングを実現します。 どのオーバーライドされた関数が呼び出されるかは実行時に解決されるため、オーバーライドは遅延バインディングを実現します。
類似点
- 両方ともクラスのメンバー関数に適用されます。
- 多態性は、両方の背後にある基本概念です。
- 関数にオーバーロードとオーバーライドを適用している間、関数名は変わりません。
結論
オーバーロードとオーバーライドは似ていますが、そうではありません。 関数はオーバーロードすることができますが、将来どのクラスもオーバーロードされた関数を再定義することはできません。 仮想関数はオーバーロードできません。 上書きすることしかできません。