2025年3月31日 星期一 乙巳(蛇)年 正月初一 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

C++继承与对象指针

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

我们在第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成员函数。这个功能如何才能实现?在之后的几节我们会作讲解。

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