C++学習の継承

3484 ワード

継承:プログラムコードの再利用度を大幅に向上させ、C++は継承をよくサポートし、
ベースクラスオブジェクトは、ベースクラスのデータが不十分で、サブクラスのすべての情報が含まれていないため、サブクラスオブジェクトに値を割り当てることはできません.ただし、サブクラスオブジェクトはベースクラスオブジェクトに値を割り当てることができます.
次の図に示します.
例えば、studentはクラスであり、GraduateStudentはstudentのサブクラスである場合、GraduateStudent gs;Student* p = &gs;
pはStudentポインタであるため、GraduateStudentオブジェクトgsのヘッダアドレスを指し、Studentオブジェクト部分のヘッダアドレスでもある.
大学院生も学生なので、大学院生対象のgsをsに与えるのも合理的です.専属大学院生の部分をカットし、大学院生対象のアドレスを学生ポインタpに付与するのも合理的であり、学生対象アドレスと大学院生対象アドレスが重なるため、pポインタを大学院生タイプに変換すると:GraduateStudent*pGs=reinterpret_cast(p); アドレスを変更する必要がなく、大学院生を操作することができます.このreinterpret_cast変換は,純粋にアドレスが変わらずポインタタイプが変化する,すなわちポインタ操作の意味が変化する.しかし、学生対象と大学院生対象の住所が重なることが前提だ.
1.親アクションの上書き
親クラスに操作があり、子クラスで再定義されていない場合は、子クラスはその操作に沿って使用できますが、親操作です.例えば、以下のプログラムでは、大学院生クラスGraduateStudentがStudentクラスを継承しており、対象gsが本人情報を表示する場合、関連する大学院生情報を表示することはできない.これは主にGraduateStudioクラスにdisplayメンバー関数がリロードされていないため、GraduateStudioクラスを使用する準備をするためには、GraduateStudioクラスで親クラスのdisplayメンバー関数を上書きする必要があります.
#include <iostream>
#include <string>
using namespace std;

class Advisor
{
	int noOfMeeting;
};

class Student
{
	string name;
	int semesterHours;
	double average;
public:
	Student(string pName = "noName")
	{
		name = pName;
		average = 0;
		semesterHours = 0;
	}
	void addCourse(int hours, double grade)
	{
		double totalGrade = (semesterHours * average + grade);
		semesterHours += hours;
		average = semesterHours ? totalGrade / semesterHours : 0;
	}
	void display()
	{
		cout << "name=\"" << name << "\"" << ", hours=" << semesterHours << ", average=" << average << endl;
	}

	int getHours()
	{
		return semesterHours;
	}
	
	double getAverage()
	{
		return average;
	}
};

class GraduateStudent : public Student
{
	Advisor advisor;
	int qualifierGrade;
public:
	GraduateStudent(string pName = "noName"):Student(pName)
	{

		qualifierGrade = 0;
	}

	int getQualifier()
	{
		return qualifierGrade;
	}

	void display()
	{
		Student::display();
		cout << "qualifierGrade=" << qualifierGrade << endl;
	}
};

int main()
{
	Student ds("Lo lee undergraduade");
	GraduateStudent gs("WU fantasy");
	ds.addCourse(3, 2.5);
	ds.display();

	gs.addCourse(3, 3.0);
	gs.display();

	return 0;
}

2.同化効果
上記のコードでは,GraduateStudentクラスがStudentクラスを継承しており,自分のアイデンティティで表現する際に独自の特色を示している.しかし、大学院生の対象として学生に複製(伝達)すると、大学院生の個性は消失し、以下のコードに示す.
void fun(Student& x)
{
	x.display();
}

int main()
{
	Student s("Lo lee undergraduate");
	GraduateStudent gs("John");
	fun(s);
	fun(gs);

	return 0;
}

コード出力は次のとおりです.
name="Lo lee undergraduate", hours=0, average=0
name="John", hours=0, average=0

出力結果から,StudentクラスオブジェクトsとGraduateStudentクラスオブジェクトgsがパラメータとしてfun関数に渡された場合,gsはfun関数では大学院生として見られず,Studentクラスオブジェクトとして扱われて動作することが分かる.