1.多型自然:
正式には、一般的なポインタ処理を行うための統一された親の使用。しかし、実際の実装は、このポインタは、サブクラスのオブジェクトを指すことがあります。
正式には、元の親クラスへの呼び出しが、実際には同じ名前のサブクラスメソッドを呼び出します。
率直に言って、ポインタによる多型は、親クラス、親クラスとサブクラスのメソッドが自分を呼び出すことができます使用することです。多型でない場合は、親クラスのポインタと呼ばれるサブクラスのために、また、親クラスのメソッドを呼び出しました。
詳細な参考:C ++の仮想関数テーブルの多型性-多型のシンプルな使用
[注]
プログラムの実行、親クラスの親クラスのオブジェクトへのポインタ、またはサブクラスのオブジェクトは、正式に解消されていない場合。唯一マルチステート機構を介して実際の対応する方法を実行します。
2.仮想関数:
親クラスの機能の方法の前に、あなたは仮想関数を仮想関数となる増やすことができ、例えば:
外部へのパッケージ、特に前者の方法は、エラーと、仮想追加することなく実施されるとき、例えば、インライン関数と、それに留意されたいです。
1 クラスの父 2 { 3 公共: 4 仮想 無効プレイ() //親クラスの仮想キーワードを増やす前に、play()メソッドは、この関数は仮想関数となっている 5 { 6 のstd :: coutの<< " これは、親クラスでありますプレイ" << STD :: ENDL; 7。 } 8。 }; 9。 10 クラスソン:パブリック父 。11 { 12は、 公衆: 13である ボイドプレイ() 14 { 15 STD :: << COUT" これは、再生のサブクラスである" << STD :: ENDL; 16 } 17 }。
3.仮想関数継承:
メンバ関数が派生クラス継承したメンバ関数にサブクラスので、[それ]、仮想宣言されている場合、仮想関数になります。
オーバーライドサブクラスでは、この仮想関数は、仮想書き込むことができない場合、それは仮想書くことが推奨され、そのような13行として、より読みやすいコード、次のようになります。
。1 クラスの父 2 { 3。 公共: 4 仮想 無効プレイ() //親クラスのplay()メソッドこの関数は仮想になり、前にvirtualキーワードを向上させる 。5 { 6。 STD :: COUT << " これは、親クラスでありますプレイ" << STD :: ENDL; 7。 } 8。 }; 9。 10 クラスソン:パブリック父 。11 { 12は 公衆: 13である 仮想 ボイド遊び() // 継承された派生クラスの仮想関数は、仮想追加することはできません、それは、コードをより読みしかしとなる前に 14 { 15 STD :: COUT <<「これはプレイのサブクラスである」 << STD :: ENDL; 16 } 17 }。
4.仮想関数の原則:
仮想関数の原理は、仮想関数テーブルによって達成され、仮想関数テーブルは、コンパイラの出ている彼は、オブジェクトに以下のコードを見て存在していない事を実行します。
1の#include <iostreamの> 2 使用して 名前空間STDを、 3つの 4 クラス父 5 { 6 公共: 7 仮想 ボイド FUNC_1(){COUT << " 父:: FUNC_1 " << ENDL。} 8 バーチャル 空隙 func_2(){COUT << " 父:: func_2 " << ENDL。} 9 バーチャル 空隙 func_3(){COUT << " 父:: func_3 " << ENDL。 12は、 13である INTメイン(ボイド) 14 { 15 父father_1; // 仮想関数テーブルは、父親の内部オブジェクトに格納されている 16 17。 COUT << " はsizeof(father_1)== " << のsizeof(father_1)<< ENDLは、 18である 。19 }
実行した後、それを印刷して、オブジェクトの父によって占有どのくらいのメモリ領域を参照。
動作結果:のsizeof(father_1)== 4
なぜ3つの仮想機能のみ4つのバイト?彼は記憶されているテーブルであるため、彼はメモリ空間オブジェクトを取りませんでした、オブジェクトは仮想関数テーブルへのポインタのみに存在し、概略側面以下、あなたは仮想関数を持っているどのように多くの関係なく、仮想関数テーブル彼:
================================================== ================================================== =======================