ポリモーフィズムの理解:
は新しいオブジェクト指向の要件です:
実際のオブジェクトの型に基づいて書き換えられた関数の呼び出しを判断します
親クラスのポインターが親クラスのオブジェクトを指している場合は、親クラスのオブジェクトで定義されている関数を呼び出します親クラス
親クラス ポインタがサブクラス オブジェクトを指している場合は、サブクラスで定義されているオーバーライドされた関数を呼び出します
解決策:
Ø C++ では、virtual キーワードを通じてポリモーフィズムがサポートされています
Ø 仮想宣言を使用します。関数を書き換えると、ポリモーフィックな特性を示すことができます
//オブジェクト指向の 3 つの主要な概念
カプセル化
は、C 言語関数の概念を打ち破ります。 。
継承
コードの再利用。 。 。 。最初に書いたコードを再利用します。 。 。
ポリモーフィズム
ポリモーフィズムは未来を利用できます。 。 。 。 。フレームワークは 1980 年代に作成されました。 。 。 。 。 。 1990 年代に書かれたコード
ポリモーフィズムは、ソフトウェア業界が追求する目標です。 。 。
//後の世代が書いたコードの機能を呼び出すことができるフレームワークを書きました
さらなる理解
//間接代入が成立するための 3 つの条件:
//1 2 つの変数を定義します。 。 。
//2 関連付けを作成します。 。 。 。
//3 *p
//ポリモーフィズムが成立する3つの条件:
//1 継承がなければならない
//2 関数の書き換えがなければならない。 。 。 C仮想関数
//3 サブクラスオブジェクトを指す親クラスポインタ(親クラス参照)が必要
//ポリモーフィズムはデザインパターンの基礎、ポリモーフィズムはフレームワークの基礎
知識ポイント1 仮想デストラクター
デストラクターは、リソースを解放する必要があり、オブジェクトを直接解放できない場合に使用します。
C *myC = new C //C は B を継承し、B はクラスを継承します。 A
delete myC; //この場合、仮想キーワードを記述する必要はありません
必要に応じて、すべてのサブクラス オブジェクトのデストラクターを実行する必要があります。親クラス ポインター リソースを介してすべてのサブクラスを解放するには (virtual キーワードを最終親クラスのデストラクターに追加する必要があります)
void howtodelete(A *base) { delete base; //这句话不会表现成多态 这种属性 }
同じクラス内で実行
child クラスは親クラスの関数をオーバーロードできません。親クラスと同じ名前の関数はその名前で上書きされます (例: 親クラスに関数 a() があり、サブクラスには関数 a() もありますが、関数 a(int b) もあります。この関数は親クラスの関数をオーバーロードするとエラーが発生します。)
オーバーロードはパラメーターの型と数に基づいて関数呼び出しを決定します。コンパイル中に
関数の書き換え
は親クラスと子クラスの間で行わなければなりません
クラスとサブクラスの関数はまったく同じプロトタイプを持つ必要があります
仮想宣言を使用するとポリモーフィズムが生じる可能性があります(仮想が使用されない場合、それは再定義と呼ばれます) )
ポリモーフィズムは、実行時に特定のオブジェクトの型に基づいて関数呼び出しを決定します
分析例:
//1 C++编译器 看到func名字 ,因子类中func名字已经存在了(名称覆盖).所以c++编译器不会去找父类的4个参数的func函数 //2 c++编译器只会在子类中,查找func函数,找到了两个func,一个是2个参数的,一个是3个参数的. //3 C++编译器开始报错..... error C2661: “Child::func”: 没有重载函数接受 4 个参数 //4 若想调用父类的func,只能加上父类的域名..这样去调用.. c1.func(1, 3, 4, 5); //c1.func(); //func函数的名字,在子类中发生了名称覆盖;子类的函数的名字,占用了父类的函数的名字的位置 //因为子类中已经有了func名字的重载形式。。。。 //编译器开始在子类中找func函数。。。。但是没有0个参数的func函数
仮想関数がクラスで宣言されている場合、コンパイラはクラス内に仮想関数テーブルを生成します
仮想関数テーブルはストレージです クラスメンバー関数ポインタのデータ構造
仮想関数テーブルはコンパイラによって自動的に生成され、維持されます
仮想メンバー関数はコンパイラによる仮想関数テーブル
仮想関数が存在する場合、各オブジェクトに 1 つ存在します 仮想関数テーブルへのポインタ (vptr ポインタ)
Call仮想関数テーブル ポインタ VPTR を介して書き換えられた関数は、プログラムの実行中に実行されるため、アドレス指定する必要があります。操作により、実際に呼び出される関数を決定できます。通常のメンバー関数の場合、呼び出される関数はコンパイル時に決定されます。効率という点では、仮想関数の効率ははるかに低くなります。
注 2:
効率上の理由から、すべてのメンバー関数を仮想関数として宣言する必要はありません
注 3: C++ コンパイラーは、HowToPrint 関数を実行するときに、それがサブクラス オブジェクトであるか、サブクラス オブジェクトであるかを区別する必要はありません。親クラスのオブジェクト