マルチ状態(より一般的Day9)
図1に示すように、多状態条件
1)多形性特性に加えて、ベースクラス、仮想関数で宣言され、そしてサブクラスで有効なカバレッジの形成は、仮想関数はポインタまたは参照によって呼び出される必要があり、それが直接多型オブジェクトによって呼び出されていない、明らかにすることができます。
2)仮想関数ポインタは、このポインタであってもよい呼び出しであれば基底クラスのポインタサブクラスオブジェクトであるように、同一の多型性を示すことができます。
クラスベース{ パブリック: 仮想 INT CAL(int型のx、int型のY){ retunr X + Y。 } // d.foo() - > FOO(&D) // 空隙FOO(ベース*本) // ベース*この=&D。 空隙 FOO(ボイド){ COUT << CAL(100、200)<< ENDL。 } }。 クラス派生:公共基本{ パブリック: INT CAL(INT A、INT B){ リターン* B; } } int型メイン(ボイド){ 由来D、 ベースB = D; COUT << b.cal(100、200である)<< ENDLは; // 呼び出しは、マルチを形成せず、基底クラスバージョンであります状態コール d.fooを(); // 子クラス・オブジェクトは、関数のfooされていないが、この一方でパスは、Base *が、それに対応して呼び出す派生型を指し*&D、あるのでthis- > CAL(100,200)ので、多型コールの形成 戻り 0 ; }
二、純粋仮想関数、抽象クラス、抽象クラスの純粋な
1、純粋仮想関数
仮想 無効ドロー(無効)= 0 ; // 純粋仮想関数
次のように純粋仮想関数の一般的な形式は次のとおりです。
仮想リターン関数名(パラメータリスト)の種類[ CONST ] = 0 ;
2、抽象クラス
クラスは純粋仮想関数が含まれている場合は1)、それは抽象クラスです。たとえば、Shapeクラスは抽象クラスで、クラスは、特定の行動が含まれていません。コンパイラは、抽象クラスのインスタンスオブジェクトを許可していません。インスタンス化した場合、次のエラーが発生します。
基底クラスは純粋仮想関数を継承しており、サブクラスがカバーされていない場合、2)さらに、次にサブクラスは抽象クラスに変換されます。
()コンストラクタ、デストラクタを含まないクラスのすべてのメンバー関数は純粋仮想関数である場合3)、このクラスは、純粋な抽象クラスと呼ばれています。
3)実施例工場パターン
パースの責任Team1 クラスPDFParse { パブリック: 無効 Prase(のconst のchar * PDFファイル)// 解析グラフィックスを、テキスト、グラフィックス機能 { OnCircle(); OnRect(); ontext(); OnImage(); // 。。。 } プライベート: 仮想 ボイド Oncircle(ボイド)= 0 ; 仮想 ボイド OnRect(ボイド)= 0 ; 仮想 ボイド ontext(ボイド)= 0 ; 仮想 ボイド OnImage(無効)= 0 ; }。 Team2负责绘图实现 クラス PDFRender:公共PDFParse { プライベート: 無効 OnCircle(無効){ ... } 無効 OnRect(無効){ ... } 無効 OnText(無効){ ... } 無効 OnImage(無効){ ... 。 }。 }。 INTメイン(ボイド){ PDFRenderレンダリング。 render.parse(" something.pdf "); // 多型は、このポインタによって実現される 戻り 0 ; }
原則4)マルチ状態実現(理解)
1:仮想関数と呼ばれる仮想キーワード述べた機能は、仮想関数は、クラスのメンバ関数を持っている必要があります。
2:クラスの仮想関数の存在は三次元仮想関数テーブルは、仮想テーブルと呼ばれた、オブジェクトのクラスへのポインタは、仮想仮想テーブルポインタが開始されました。仮想テーブルは、クラスに対応し、オブジェクトに対応する仮想テーブルポインタです。
3:インタフェース多型の複数の実装では、オブジェクト指向のコア、多型および機能の多型は、クラスに分類されます。
4:多型は、動的バインディングと組み合わせ、仮想機能を実行します。
5:純粋仮想関数は= 0と一緒に仮想関数です。
6:抽象クラスは、少なくとも一つの純粋仮想関数を含むクラスを意味します。
原則:
(1)コンパイラのため、コンパイル時に非仮想関数呼び出しアドレスがバインドされた、このような結合は、事前バインディングと呼ばれています。それは良い、実行をコンパイル時にバインドされているように、基本クラスまたは参照に、基本クラスのポインタまでの形状は、同じ関数を呼び出した場合にのみ、非仮想、あるいはサブクラスのポインタは、呼び出し元の関数を参照する場合これは、変更することはできません。
(2)(1)サブクラスと呼ばれる基本クラスへの関数ポインタを使用するには、仮想関数で使用することが必要です
仮想関数が存在する場合(3)、それは任意のクラスのクラスに仮想関数テーブルポインタを追加する(3つのポインタは、関数ポインタは、ポインタは、典型的には、仮想テーブルの後半は、仮想関数ポインタであります上記のように、それは二つのポインタことが理解される配列、)、)(FOO、仮想関数テーブル(略称仮想テーブル)を指し、対象における仮想テーブルポインタサイズを表す4つのバイトは、オブジェクトの仮想テーブルに属しているが、仮想によってありませんテーブルポインタは、内容を要します。図基底クラスのfoo()仮想関数も、そこに仮想関数テーブルは、サブクラスが継承し、仮想関数の後であり、そのクラスのアドレスを追加する機能のクラスFOO A()の開始アドレスをカバー。バー機能が書き換えられていない、完全な機能を継承し、開始アドレスは変更されません。
遅延バインディング仮想テーブルポインタvptrに属する(4)は、参照される型への実際のまたは実際のポインタの種類に応じて呼び出されます。各オブジェクトの仮想関数を呼び出すと、アレイは開始アドレスと同一のインデックスを持っているように、仮想関数によって索引付けされるべきです。だから、正しく初期化された仮想テーブルポインタは非常に重要です。作成し、それを初期化するときに仮想テーブルポインタがありますか?仮想テーブルポインタが実際に作成さで、コンストラクタで初期化される(3)また、仮想オブジェクト・テーブル・ポインタの一部、メモリサイズの4バイト、最初の作成およびコンストラクタで初期化するように見えるであろう、と述べました付与されました。
(5)基本クラスの構成に最初、基本クラスのサブオブジェクトを構築する場合、コンパイラは、基本クラスの仮想テーブルを作成し、初期化するために、親クラスが仮想関数を持っている見、ときにクラスオブジェクトのコンストラクタ、発見サブクラス仮想機能は、FOO()関数が覆われるように、基本クラスの仮想テーブルカバーをカバーするために必要とされるが、バー()関数は、覆われていません。ポインタ又は参照の呼び出しによって実現することができる理由多型理由であるサブクラスにおいて、(ベース・クラス、仮想テーブルポインタは区別される)は、仮想テーブルポインタを有します。オブジェクトを直接呼び出している間、仮想テーブルポインタインデックス、直接転写体機能なし((この機能は、親クラスの仮想関数は、オブジェクトを介してベースクラスを呼び出す実装、実際には、このポインタ内にある役割を果たした)を除きます)。
第三に、仮想デストラクタ
1、導入
デストラクタポインタをサブクラス化するために、基本クラスのオブジェクトは、基本クラスのデストラクタを呼び出すことができますし、デストラクタのサブクラスを呼び出すことができないときは、この方法は、以前に学習ある基底クラスへのポインタ下方行います破壊のためのモデリング。実際には、これは行われませんが、仮想デストラクタの使用が解決します。
クラスBase {
パブリック:
塩基(ボイド){
裁判所未満<< "ベース::ベース()" <<てendl;
}
仮想〜基地(無効){
裁判所未満<< "ベース::〜ベース()" <<てendl;
}
}。
派生クラス:公共ベース{
パブリック:
誘導された(ボイド){
裁判所未満<< "派生::派生()" <<てendl;
}
〜派生(無効){
裁判所未満<< "派生::〜派生()" <<てendl;
}
}。
(ボイド){int型メイン
基本*のPB =新しい派生;仮想デストラクタを宣言されていない場合は、//、メモリはメモリリークのリスクを持ってこのようにリリースされる予定
PBを削除します。
0を返します。
}
次いで、基底クラス、仮想関数、デストラクタサブクラスのデストラクタが仮想関数である場合、基本クラスのデストラクタの効果的なカバレッジであってもよいです。基本クラスのポインタのサブクラスを削除するには、この時間は、実際の呼び出しは、デストラクタサブクラスで、サブクラスのデストラクタは、上記の問題を回避するために、基本クラスのデストラクタを呼び出します。
第四に、練習 - 給与計算
従業員の属性:名前、ジョブ番号、ジョブレベル、ペイ・フォー・パフォーマンス、出席
マネージャー:パフォーマンスボーナス(元/月)
技術者:R&D手当(元/時間)
売主:手数料率(パーセント)
給与=基本給+パフォーマンスの賃金
基本賃金=キャリアレベルの出席クレジット*
ペイ・フォー・パフォーマンス:により異なるジョブと異なるに
一般スタッフ:半分基本給
マネージャー:パフォーマンスボーナス*パフォーマンスファクター(手入力)
技術:因子(手入力)労働時間のR&D手当*進捗番号
売主:セールス度(手動入力)*パーセント
テクニカルディレクター:(技術者の給与+パフォーマンスのためのパフォーマンスマネージャの有料)/ 2
セールスディレクター:(販売員のパフォーマンスマネージャのパフォーマンスの賃金給与+)/ 2
結果:印刷従業員データは、あなたが給与を計算し、入力データを入力する必要があります