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メンバー関数を上書きする必要があります.
2.同化効果
上記のコードでは,GraduateStudentクラスがStudentクラスを継承しており,自分のアイデンティティで表現する際に独自の特色を示している.しかし、大学院生の対象として学生に複製(伝達)すると、大学院生の個性は消失し、以下のコードに示す.
コード出力は次のとおりです.
出力結果から,StudentクラスオブジェクトsとGraduateStudentクラスオブジェクトgsがパラメータとしてfun関数に渡された場合,gsはfun関数では大学院生として見られず,Studentクラスオブジェクトとして扱われて動作することが分かる.
ベースクラスオブジェクトは、ベースクラスのデータが不十分で、サブクラスのすべての情報が含まれていないため、サブクラスオブジェクトに値を割り当てることはできません.ただし、サブクラスオブジェクトはベースクラスオブジェクトに値を割り当てることができます.
次の図に示します.
例えば、studentはクラスであり、GraduateStudentはstudentのサブクラスである場合、GraduateStudent gs;Student* p = &gs;
pはStudentポインタであるため、GraduateStudentオブジェクトgsのヘッダアドレスを指し、Studentオブジェクト部分のヘッダアドレスでもある.
大学院生も学生なので、大学院生対象のgsをsに与えるのも合理的です.専属大学院生の部分をカットし、大学院生対象のアドレスを学生ポインタpに付与するのも合理的であり、学生対象アドレスと大学院生対象アドレスが重なるため、pポインタを大学院生タイプに変換すると:GraduateStudent*pGs=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クラスオブジェクトとして扱われて動作することが分かる.