[C ++] - 私たちは、多型の基本を理解する必要があります

まず、多型は何ですか?

  • 多型は、各インタビューで、C ++を聞いてきますし、きっとモジュール、私たちはこのようにそれを置く、多型は、完全に異なるオブジェクトに動作を完了するまでの時間は、異なる状態を持っている場合、様々な形態です。
  • あいまいな言葉は、ギブ・栗ヘクタール、例えば、ヒトやドッグフードなどの多くの形態が存在する、行動のこの種を食べて、キャットフードは異なるの同じ行為の多状態の概念を反映した様々なアクションであり、異なる効果を完了するために、オブジェクト。

    ここにいることは、あなたが前に私に同じ質問を告げたでしょうか?-パッケージがコードモジュラー継承既存のコードを拡張することができるようにしてもよい、その目的は、コードの再利用です。多型のそれの役割は何ですか?実際には、多型の目的は、インターフェイスを再利用することで、関数呼び出しは、同じインターフェイスを介して目的を達成するために彼らの方法を容易に適合させることができます。

第二に、形成条件とポリモーフィズムを実現

2.1成形条件(3つの条件が必要不可欠です!)

  • 継承されてきました
  • それは書き換える必要があります(同じ関数名、同じパラメータ、同じ戻り値の型)
  • オブジェクト参照親クラスのサブクラスをポインティング

  • 文:基本クラスの前に派生機能でオーバーライド仮想キーワード
  • 私たちは、オブジェクトの実際の実行時の型の関数を呼び出すために応答します。オブジェクト・タイプが派生クラスである場合、派生クラスが呼び出される、オブジェクト・タイプは基本クラスである場合、ベースクラスが呼び出され

アメリカ2.2以上を達成するために

以下は、下のスクリーンショット多型の結果についての簡単な実装です。

#include <iostream>
#include <stdlib.h>
using namespace std;

class animal 
{
public:
	virtual void sleep()
	{
		cout << "animal sleep......" << endl;
	}
};
class fish :public animal
{
	void sleep()
	{
		cout << "fish sleep......" << endl;
	}
};
int main()
{
	fish fh;
	animal *ani = &fh;
	ani->sleep();
	system("pause");
	return 0;
}

ここに画像を挿入説明

第三に、多型の原則を達成するために

私たちは、(非常に長いが、非常に便利)、これらの結果の分析を行った:動物クラスは仮想関数を持っていることが判明し、コンパイル時にコンパイラは、コンパイラは、仮想テーブルを作成するために、各仮想関数のためのクラスが含まれます、このテーブルは、仮想テーブル内の各仮想関数のアドレスを格納し、一次元アレイです。また、基底クラスの仮想関数、仮想関数サブクラスが(基底クラスの仮想関数のメンバーは、デフォルトのサブクラスは仮想関数を持っている場合)、どのように仮想テーブルを見つけるために持っていますか?(疑問符面)は、実際には、コンパイラはさらにvptrへのポインタを提供するために、各クラスの仮想テーブルのオブジェクト、見下す、オブジェクトに仮想テーブルポインタは、プログラムが実行されている場合、コンパイラは、オブジェクトに基づいているすべてのクラスに属しvptr初期化し、そのクラスの仮想テーブルの正しいポイントをvptrできるように入力します。

魚はクラス仮想テーブルvptr向けられるようにプログラムオブジェクト内の上記の目的において、ANI実際のタイプの魚を指摘しました。スリープ関数の呼び出しは、仮想アドレステーブルの機能は、スリープ機能のような魚で発見された場合、それは今それの結果については間違いないです。

私は今、その時以来、プログラムがオブジェクトを検索するために実行され、ハッハッハ、疑問を持っている。それを初期化するために、仮想関数、仮想関数と呼ばれる仮想テーブルポインタが仮想関数が初期化されているか、非常に重要である必要がありますか?あるいは、どのような場所に初期化されますか?心配は、ダウン見てはいけない、実際には、答えは作成してコンストラクタで仮想テーブルを初期化することで、我々は派生クラスのオブジェクトをインスタンス化するとき、彼は最初の基底クラスのコンストラクタを呼ぶだろう、それは最初の仮想テーブルを初期化しますコンストラクタサブクラスを呼び出すときvptrポインタは、基本クラスの仮想テーブルを指すように、サブクラス仮想テーブルポインタオブジェクトは、上記の手順で、その仮想テーブルを指すように初期化され、オブジェクトのFH FISH完成した構造、終点ANIの魚は、オブジェクトクラスであり、仮想テーブルポインタが最終的に、仮想テーブルの魚を指しているため、仮想テーブルポインタは、変換タイプ、コールani->睡眠()の後に、既に魚クラスの仮想テーブルでしたスリープ機能と呼ばれる魚の一種であります

  • すべてのすべてで、各内部オブジェクトは、仮想テーブルポインタを持っている単語や短いが、仮想関数を呼び出すために、仮想テーブルポインタは、仮想テーブルのこの種を指すように初期化されるので、プログラムが実行され、関係なく、あなたのオブジェクトのどのように変化する仮想テーブルポインタが変更されていない内部のタイプで、彼はだ、それは常に自分の仮想テーブルを指すようになりますが、別のクラスの仮想テーブルを指していません、それは動的な機能を再利用します。

第四に、他のマルチ状態コンセプト

  • 仮想関数が述べられた仮想キーワードの機能を使用して呼び出され、仮想関数は、クラスのメンバ関数である必要があります
  • 仮想関数の存在は、仮想テーブルと呼ばれる一次元の仮想関数テーブルを持っています。Objectクラスは、ダミーの先頭を指す仮想テーブルポインタを持っています。そして、仮想テーブルには、クラスに対応しています。
  • 多型は、クラスに分類されるインターフェイス、オブジェクト指向コア、多型および機能の多型の実装の複数であります
  • 多型は、仮想関数で達成ダイナミックな結合と結合され
    た仮想関数は何ですか?
    仮想関数が基底クラスの仮想関数キーワードを使用して宣言された場合は、派生クラスで定義された基本クラスの仮想関数を再定義し、静的関数にリンクされていないコンパイラ指示し
    、純粋仮想関数であるかのか?
    あなたはより良いオブジェクトに適用するために、派生クラスで関数を再定義するためには、基本クラスで仮想関数を定義したいことがありますが、基本クラスに仮想関数の意味の実装を与えたいことができない、この時間純粋仮想関数での役割を果たします
class animal   //这是基类
{
public:
	virtual void sleep()
	{
		cout << "animal sleep......" << endl;
	}
	virtual void eat() = 0;   //声明为纯虚函数
};

それを参照してください、食べては、基底クラスの関数宣言は、コンパイラではなく、主な機能を伝えることです純粋仮想関数である持っています。派生クラスは、食べる機能を再定義することに意味のある操作を与えることができます

第五に、抽象クラス

抽象クラス:抽象クラスは、世界のいくつかは、そのような人、動物、より広いカテゴリーの一部として特定のオブジェクトを、見つけることができない特定の種類の一般化を比較しない記述します。

  • (また、インターフェース・クラスと呼ばれる)抽象クラスと呼ばれる純粋仮想関数、オブジェクトをインスタンス化することができない抽象クラスを含みます。
  • 派生クラスの後にのみオブジェクトをインスタンス化する純粋仮想関数、派生クラスをオーバーライドするオブジェクトインスタンスを継承することができません。
  • 派生クラスの純粋仮想関数の仕様をオーバーライドする必要があり、追加の純粋仮想関数は、インターフェイスの継承を反映しています。
  • 私たちは、派生クラスが仮想関数をオーバーライドする場合は、オブジェクトをインスタンス化することはできませんので、実際には、派生クラスの仮想関数の書き換えを強制的に仮想関数機構であり、それを言うことができます。
    興味を持っている。ここを見てとることができ、例えば、次のとおりです。
#include <iostream>
#include <stdlib.h>
using namespace std;
class Car   //基类
{
public:
	virtual void Drive() = 0;//纯虚函数
};
class Benz :public Car   //子类Benz
{
public:
	virtual void Drive()
	{
		cout << "Benz-舒适" << endl;
	}
};
class BMW :public Car   //子类BMW
{
public:
	virtual void Drive()
	{
		cout << "BMW-操控" << endl;
	}
};
int main()
{
	Car* pBenz = new Benz;
	pBenz->Drive();
	Car* pBMW = new BMW;
	pBMW->Drive();
	system("pause");
	return 0;
}

ここに画像を挿入説明
大多数のユーザーが特定の謙虚の採用ことを示唆していることの問題の望みは何ですか

公開された33元の記事 ウォン称賛13 ビュー1042

おすすめ

転載: blog.csdn.net/Vicky_Cr/article/details/105033872