C++教程:C++繼承與對象指針
2020-05-23 14:25:31
供稿:網友
我們在第14章的最后學習了對象指針,并且在編寫鏈表類的過程中已經能熟練地使用它了。現在有了繼承之后,我們的心中有了疑問:父類指針能否指向子類對象?子類指針能否指向父類對象?如果那樣使用指針,對象的功能是否會受到限制呢?
父類指針與子類對象
我們修改程序17.3.1,用程序的運行結果來解答我們的疑問:
//student.h和undergraduate.h同程序17.3.1
//main.cpp
#include <iostream>
#include "undergraduate.h"
using namespace std;
int main()
{
Undergraduate s1;//新建一個本科生對象
Undergraduate *s1p;//新建一個子類的對象指針
student s2;
student *s2p;//新建一個父類的對象指針
s1p=&s2;//這行程序出錯了
s2p=&s1;
s1.set("Tom",21,178,60);
cout <<s1.sname <<s1.sage <<endl;
s2p->set("Jon",22,185,68);
cout <<s1.sname <<s1.sage <<endl;
s1p->setGPA(2.5);
s2p->setGPA(3.0); //這行程序出錯了
return 0;
}
編譯結果:
main.cpp(10) : error C2440: '=' : cannot convert from 'class student *' to 'class Undergraduate *'
main.cpp(17) : error C2039: 'setGPA' : is not a member of 'student'
根據編譯結果,我們可以看到,在公有繼承情況下父類的對象指針指向子類對象是允許的。如s2p學生指針指向本科生s1,因為本科生也是學生;子類的對象指針指向父類是禁止的。如s1p本科生指針不能指向學生s2,因為學生不一定是本科生。
此外,如果我們用父類的對象指針指向子類對象,那么這個指針無法使用子類中擴展出的成員。如s2p指針無法設置本科生的績點,因為使用了學生指針,本科生就變成了學生的身份,學生身份不再有設置績點的功能。
我們再次修改程序17.3.1,使得它能夠運行:(程序17.5)
//student.h和undergraduate.h同程序17.3.1
//main.cpp
#include <iostream>
#include "undergraduate.h"
using namespace std;
int main()
{
Undergraduate s1;
student s2;
student *s2p;
s2p=&s1;
s1.set("Tom",21,178,60);
cout <<s1.sname() <<'/t' <<s1.sage() <<endl;
s2p->set("Jon",22,185,68);
cout <<s1.sname() <<'/t' <<s1.sage() <<endl;
return 0;
}
運行結果:
Constructing a student without parameter...
Constructing a student without parameter...
Tom 21
Jon 22
現在程序能夠正常運行了??梢姡胹1設置本科生信息和用s2p指針設置學生信息都是可行的。
覆蓋(Overlap)
假設我們為學生類和本科生類都寫了一個名為study的成員函數。兩者的名稱相同,參數表相同,實現卻不相同。當子類和父類有著兩個名字和參數表完全相同的函數時,我們把這個現象稱為覆蓋(Overlap)。如下面的代碼:
//student.h
class student//學生類作為父類
{
public:
……
void study();
protected:
char name[10];
int age;
int height;
int weight;
};
……
void student::study()
{
cout <<"隨便學些什么。" <<endl;
return;
}
//undergraduate.h
class Undergraduate:public student
{
public:
……
void study();
protected:
double GPA;//本科生績點
};
……
void Undergraduate::study()
{
cout <<"學習高等數學和大學英語。" <<endl;
return;
}
如果有一個本科生對象s1和一個學生對象s2,那么顯然s1.study()會是學習高等數學和大學英語,s2.study()會是隨便學些什么。但是,如果有一個學生類的指針sp,它也能指向本科生對象,這時調用sp->study()會是怎么樣的呢?我們發現,即使它指向一個本科生對象,它也只能“隨便學些什么”。這樣的結果在情理之中,卻并不是我們期望的。我們希望程序能夠“猜”到sp指針指向了哪種對象,并且調用各自的study成員函數。這個功能如何才能實現?在之后的幾節我們會作講解。