C++ のポリモーフィズム
ポリモーフィズムという言葉 形が多いという意味です。通常、ポリモーフィズムは、クラスの階層があり、それらが継承によって関連付けられている場合に発生します。
C++ ポリモーフィズムとは、メンバー関数を呼び出すと、その関数を呼び出すオブジェクトのタイプに応じて、異なる関数が実行されることを意味します。
基本クラスが他の 2 つのクラスによって派生された次の例を検討してください -
ライブデモ#include <iostream> using namespace std; class Shape { protected: int width, height; public: Shape( int a = 0, int b = 0){ width = a; height = b; } int area() { cout << "Parent class area :" <<endl; return 0; } }; class Rectangle: public Shape { public: Rectangle( int a = 0, int b = 0):Shape(a, b) { } int area () { cout << "Rectangle class area :" <<endl; return (width * height); } }; class Triangle: public Shape { public: Triangle( int a = 0, int b = 0):Shape(a, b) { } int area () { cout << "Triangle class area :" <<endl; return (width * height / 2); } }; // Main function for the program int main() { Shape *shape; Rectangle rec(10,7); Triangle tri(10,5); // store the address of Rectangle shape = &rec; // call rectangle area. shape->area(); // store the address of Triangle shape = &tri; // call triangle area. shape->area(); return 0; }
上記のコードをコンパイルして実行すると、次の結果が生成されます −
Parent class area : Parent class area :
出力が正しくない理由は、関数 area() の呼び出しが、基本クラスで定義されたバージョンとしてコンパイラーによって 1 回設定されているためです。これは静的解像度と呼ばれます 関数呼び出しの、または静的リンケージ - プログラムが実行される前に、関数呼び出しが修正されます。これは、アーリー バインディングとも呼ばれます。 プログラムのコンパイル中に area() 関数が設定されるためです。
しかしここで、プログラムを少し変更して、Shape クラスの area() の宣言の前にキーワード virtual を付けてみましょう。 このように見えるように −
class Shape { protected: int width, height; public: Shape( int a = 0, int b = 0) { width = a; height = b; } virtual int area() { cout << "Parent class area :" <<endl; return 0; } };
このわずかな変更の後、前のサンプルコードをコンパイルして実行すると、次の結果が生成されます-
Rectangle class area Triangle class area
今回は、コンパイラはポインタの型ではなく内容を調べます。したがって、tri および rec クラスのオブジェクトのアドレスは *shape に格納されるため、それぞれの area() 関数が呼び出されます。
ご覧のとおり、各子クラスには関数 area() の個別の実装があります。これがポリモーフィズムの仕組みです が一般的に使用されます。同じ名前の関数を持つさまざまなクラスがあり、パラメーターも同じですが、実装が異なります。
仮想関数
バーチャル function は、キーワード virtual を使用して宣言された基底クラスの関数です .基底クラスで仮想関数を定義し、派生クラスで別のバージョンを使用すると、この関数の静的リンケージが不要であることをコンパイラに通知します。
私たちが望んでいるのは、プログラムの任意の時点で呼び出される関数が、呼び出されるオブジェクトの種類に基づいて選択されることです。この種の操作は、動的リンクと呼ばれます。 、または遅延バインディング .
純粋仮想関数
基本クラスに仮想関数を含めて、そのクラスのオブジェクトに合わせて派生クラスで再定義できるようにすることは可能ですが、基本クラスの関数に与えることができる意味のある定義はありません。 .
基本クラスの仮想関数 area() を次のように変更できます −
class Shape { protected: int width, height; public: Shape(int a = 0, int b = 0) { width = a; height = b; } // pure virtual function virtual int area() = 0; };
=0 は、関数に本体がなく、上記の仮想関数が 純粋仮想関数 と呼ばれることをコンパイラに伝えます .
C言語