您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

C++继承与对象指针

时间:01-10来源:作者:点击数:

我们在第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

现在程序能够正常运行了。可见,用s1设置本科生信息和用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成员函数。这个功能如何才能实现?在之后的几节我们会作讲解。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门