【C++】多態まとめ

3336 ワード

マルチステート
マルチステートはどのようにバインドを実現しますか?
マルチステートバインドには、静的バインド、すなわちコンパイル時マルチステートと、動的バインド、すなわち実行時マルチステートの2つのケースがあります.
  • コンパイル時マルチステート:
  • リロードによって実現されます.非虚関数のメンバーにとって、システムはコンパイル時に、関数のパラメータの違いに従って実現する操作をバインドし、コンパイル時にどの関数を呼び出すかを決定する.
  • 運転時マルチステート:
  • 簡単に言えば、虚関数は動的バインドの基礎である.動的バインドは、実行時のマルチステートを実現する基礎です.動的バインディングをトリガーするには、(1)動的バインディングを行うには虚関数のみ、非虚関数は動的バインディングを行わないという2つの条件を満たす必要があります.(2)関数呼び出しは、ベースクラスタイプの参照またはポインタで行う必要があります.ベースクラスポインタまたはベースクラスリファレンスをパラメータとして使用すると、実パラメータが異なる派生クラス(またはベースクラス)のポインタまたはリファレンスに伝達され、関数内部で動的バインドがトリガーされ、実行時にマルチステートが実現されます.
    だから、なぜ一般関数を呼び出すのが虚関数を呼び出すよりも効率的なのか.
    通常の関数は静的に結合されているため、呼び出し虚関数は動的に結合されている.
  • 静的アセンブリ:コンパイル時に関数のアドレスが決定され、callが呼び出されます.
  • 動的アセンブリ:まずオブジェクトのヘッダアドレスを取得し、次にダミー関数テーブルのヘッダアドレスを参照解除した後、オフセット量を加えて、調整するダミー関数を見つけ、call呼び出します.

  • 明らかに動的アセンブリは静的アセンブリよりも操作が多く、時間がかかるに違いない.
    なぜ虚関数テーブル(関数ポインタの配列を格納する)を使用するのですか?
  • はマルチステートを実現し、親オブジェクトのポインタは親オブジェクトに対して呼び出されるのは親クラスの虚関数であり、子クラスに対して呼び出されるのは子クラスの虚関数である.
  • 同じクラスの複数のオブジェクトの虚関数テーブルは同じであるため、クラス独自の虚関数と継承された虚関数、親を書き換える虚関数が独自の虚関数テーブルに存在するスペースを節約することができます.

  • マルチ継承虚関数オブジェクトモデル
    このブログを参照:http://blog.csdn.net/dream_1996/article/details/70176600
    なぜベースクラスの構造関数を虚関数として定義するのですか?
    派生クラスをベースクラスで操作する場合、ベースクラスの解析関数を実行するのを防止するために、派生クラスの解析関数は実行されません.このような削除はベースクラスのオブジェクトのみを削除することができるため、サブクラスのオブジェクトを削除することができず、削除の半分のイメージを形成し、メモリ漏れをもたらす.
    なぜベースクラスの解析関数を虚関数として定義すればサブクラスの解析関数を呼び出すことができるのでしょうか.次のコードを見てください
    #include
    using namespace std;
    
    class Base
    {
    public:
    	Base() {};
    	~Base() 
    	{
    		cout << "delete Base" << endl;
    	};
    };
    
    class Derived : public Base
    {
    public:
    	Derived() {};
    	~Derived()
    	{
    		cout << "delete Derived" << endl;
    
    	};
    };
    int main()
    {
    	//  1
    	Base* p1 = new Derived;
    	delete p1;
    	//                     ,                ,
    	//                 ,                  。
    	//                   ,      ,              
    	//     ,             。
    	//                 ,                  ,
    	//             ,     ,                
    
    	system("pause");
    }

    なぜ子クラスと親クラスの関数名が異なり、書き換えを構成できるのでしょうか.
    コンパイラは解析関数の名前を特殊に処理しているので,内部関数名は同じである.
    抽象クラス
    抽象クラスは虚関数を利用した延長である
    virtual void Display() = 0;//    

    虚関数を含むクラスは抽象クラス、インタフェースクラスとも呼ばれ、オブジェクトをインスタンス化できません
    抽象クラス応用
    抽象クラスは継承に用いられ、複数のサブクラスが同じ抽象クラスを継承すれば、この共通の親クラスの存虚関数を書き換えることができ、そうすると私たちは親クラスのポインタで子クラスを受信し、私たちはどの子クラスを親クラスに伝えるか、その子クラスのメソッドを呼び出し、便利かどうか、抽象クラスも規範化されたプログラミングである.
    C++ static
  • クラスの静的メンバーはこのクラスに属し、クラスに属する各オブジェクト
  • である.
  • ベースクラスの静的メンバーは、このベースクラスがどれだけのサブクラスを派生しても、このような静的メンバーしかありません.
  • 使用時の注意点:
  • (1)静的メソッドはクラスの静的メンバーのみにアクセスでき、クラスの非静的メンバーにアクセスできない.(2)非静的メソッドは、クラスの静的メンバーにアクセスしてもよいし、クラスの非静的メンバーにアクセスしてもよい.(3)静的メソッドは,インスタンスで呼び出すこともクラス名で呼び出すこともできる.
    c中static
  • グローバル変数を修飾し、変数の接続属性を変更し、他のファイル呼び出しができず、ストレージ属性を変更しない.
  • ローカル変数を修飾し、ストレージ属性を変更し、ストレージ帯域の静的グローバル領域に変更します.ローカル変数に属するため、接続属性は変更されません.