C ++での関数のオーバーロードとオーバーライドの違い
コンテンツ
で過負荷’オーバーロードされた関数を、同じ関数名で、パラメーターの数とタイプが異なるように再定義します。でオーバーライドするオーバーライドされた関数のプロトタイプはプログラム全体で同じですが、オーバーライドされる関数の前に基本クラスのキーワード「仮想」が付けられ、キーワードのない派生クラスによって再定義されます。
多態性は、OOPの重要な機能の1つです。単に「1つの名前を複数のフォームに使用する」ことを意味します。ポリモーフィズムは、「関数のオーバーロード」、「演算子のオーバーロード」、および「仮想関数」を使用して実装できます。 「オーバーロード」と「オーバーライド」の両方は、ポリモーフィズムの概念を暗示しています。ここで、「オーバーロード」はコンパイル時のポリモーフィズムであり、「オーバーライド」は実行時のポリモーフィズムです。 「オーバーロード」と「オーバーライド」の主な違いについて話す場合、さらに勉強します。
さらに、比較チャートを使用して、オーバーロードとオーバーライドの違いを調べます。
- 比較表
- 定義
- 主な違い
- 類似点
- 結論
比較表:
比較の根拠 | 過負荷 | オーバーライド |
---|---|---|
プロトタイプ | プロトタイプは、パラメーターの数またはタイプが異なる場合があるため異なります。 | プロトタイプのすべての側面は同じでなければなりません。 |
キーワード | オーバーロード中にキーワードは適用されません。 | オーバーライドされる関数は、基本クラスでキーワードvirtualが先行します。 |
識別要因 | 呼び出される関数のバージョンを決定するパラメーターの数またはタイプが異なります。 | どのクラス関数がポインターによって呼び出されているかは、そのポインターに割り当てられているクラスオブジェクトのアドレスによって決まります。 |
パターンを定義する | 関数は同じ名前で再定義されますが、パラメーターの数とタイプが異なります。 | 関数は定義され、メインクラスでキーワードvirtualが先行し、キーワードが派生した派生クラスで再定義されます。 |
達成の時間 | コンパイル時間。 | 実行時間。 |
コンストラクター/仮想関数 | コンストラクターはオーバーロードできます。 | 仮想機能はオーバーライドできます。 |
デストラクタ | デストラクタはオーバーロードできません。 | デストラクタはオーバーライドできます。 |
バインディング | オーバーロードは早期バインディングを実現します。 | オーバーライドとは、遅延バインディングを指します。 |
オーバーロードの定義
コンパイル時のポリモーフィズムは「オーバーロード」と呼ばれます。オーバーロードはポリモーフィズムの概念から生成されるため、「複数のメソッドの共通インターフェース」を提供します。つまり、関数がオーバーロードされると、再定義されている間は同じ関数名が含まれます。
オーバーロードされた関数は、「パラメーターの数またはタイプ」が異なるため、オーバーロードされた関数を別の関数と区別します。このようにして、コンパイラはどのオーバーロード関数が呼び出されているかを認識します。最も一般的なオーバーロード関数は「コンストラクター」です。 「コンストラクタのコピー」は一種の「コンストラクタのオーバーロード」です。
C ++でのオーバーロードの実装
クラスオーバーロード{int a、b; public:int load(int x){//最初のload()関数a = x;を返します; } int load(int x、int y){// second load()function 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つの整数パラメーターを受け入れるという方法で区別できます。クラスオーバーロードのオブジェクトが単一のパラメーターでload()関数を呼び出すと、最初にload()関数が呼び出されます。オブジェクトが2つのパラメーターを渡してload()関数を呼び出すと、2番目のload()関数が呼び出されます。
オーバーライドの定義
実行時に達成される多態性は、「オーバーライド」と呼ばれます。これは、「継承」と「仮想関数」を使用して達成されます。オーバーライドされる関数は、基本クラスでキーワード「仮想」が先行し、キーワードのない派生クラスで再定義されます。
オーバーライドの場合に覚えておくべき最も重要なことの1つは、派生クラスが再定義している間、オーバーライドされた関数のプロトタイプを変更してはならないことです。オーバーライドされた関数に呼び出しが与えられると、C ++は、関数の呼び出しが行われる「ポインターが指すオブジェクトのタイプ」に基づいて、呼び出される関数のバージョンを決定します。
C ++でのオーバーライドの実装
class base {public:virtual void funct(){//基本クラスの仮想関数cout << "これは基本クラスfunct()"; }}; classderived1:public base {public:void funct(){//派生クラス1で再定義された基本クラスの仮想関数cout << "これは派生クラス1 funct()"; }}; class derived2:public base {public:void funct(){//派生クラスで再定義された基本クラスの仮想関数cout << "これは派生クラス2 funct()"; }}; int main(){base * p、b; derived1 d1; derived2 d2; * p =&b; p-> funct(); //基本クラスfunct()を呼び出します。 * p =&d1; p-> funct(); // derived1クラスfunct()を呼び出します。 * p =&d2; p-> funct(); // derived2クラスfunct()を呼び出します。 0を返します。 }
ここには、2つの派生クラスによってパブリックに継承される単一の基本クラスがあります。仮想関数は、キーワード「仮想」を使用して基本クラスで定義され、キーワードなしの両方の派生クラスによって再定義されます。 main()で、基本クラスはポインター変数「p」とオブジェクト「b」を作成します。 「derived1」クラスはオブジェクトd1を作成し、派生2クラスはオブジェクトd2を作成します。
これで、最初に基本クラスのオブジェクト「b」のアドレスが基本クラス「p」のポインターに割り当てられます。 「p」は関数funct()を呼び出すため、基本クラスの関数が呼び出されます。次に、派生1クラスオブジェクト「d1」のアドレスがポインター「p」に割り当てられ、再びfunct()が呼び出されます。ここでは、派生クラスの関数funct()が実行されます。最後に、ポインタ「p」が派生2クラスのオブジェクトに割り当てられます。次に、「p」は、派生クラスの関数funct()を実行する関数funct()を呼び出します。
derived1 / derived2クラスがfunct()を再定義しなかった場合、仮想関数は「階層的」であるため、基本クラスのfunct()が呼び出されます。
- オーバーロードされている関数のプロトタイプは、オーバーロードされた関数に渡されるパラメーターのタイプと数のために異なります。一方、オーバーライドされた関数のプロトタイプは変更されません。オーバーライドされた関数は、属するクラスが同じタイプとパラメーター数で異なるアクションを実行するためです。
- オーバーロードされた関数名の前にはキーワードがありませんが、オーバーライドされた関数の名前の前には、基本クラスのkeyord「Virtual」のみが付きます。
- どのオーバーロード関数が呼び出されるかは、関数に渡されるパラメーターのタイプまたは数によって異なります。呼び出されたクラスのオーバーライドされた関数は、関数を呼び出したポインターに割り当てられているクラスのオブジェクトアドレスに依存します。
- どのオーバーロード関数を呼び出すかは、コンパイル時に解決されます。呼び出されるオーバーライドされた関数は、実行時に解決されます。
- コンストラクタはオーバーロードできますが、オーバーライドできません。
- デストラクタはオーバーロードできませんが、オーバーライドできます。
- オーバーロードにより、どのオーバーロード関数が呼び出されるかがコンパイル時に解決されるため、早期バインディングが実現します。オーバーライドすると、どのオーバーライドされた関数が呼び出されるかが実行時に解決されるため、遅延バインディングが実現します。
類似点
- どちらもクラスのメンバー関数に適用されます。
- ポリモーフィズムは、両方の背後にある基本的な概念です。
- 関数にオーバーロードとオーバーライドを適用している間、関数名は同じままです。
結論
オーバーロードとオーバーライドは同様に見えますが、そうではありません。関数はオーバーロードできますが、将来、どのクラスでもオーバーロードされた関数をさらに再定義することはできません。仮想関数はオーバーロードできません。オーバーライドのみ可能です。