C++学习之继承

继承:使程序代码的重用度大幅度地提高了,而C++对继承有很好的支持,

基类对象不能给子类对象赋值,因为基类中的数据不充分,不含有子类全部的信息,
但是子类对象可以给基类对象赋值。

如下图所示:

例如:
student是一类,GraduateStudent是student的子类,那么
GraduateStudent gs;
Student* p = &gs;

由于p是Student指针,指向GraduateStudent对象gs的首地址,它恰好也是其中Student对象部分的首地址。

因为研究生也是学生,所以研究生对象gs赋值给s也是合理的。它裁去了专属研究生的部分,而且将研究生对象的地址赋给学生指针p也是合理的,由于学生对象地址和研究生对象地址重合,所以,p指针若转换为研究生类型是:
GraduateStudent* pGs = reinterpret_cast<GraduateStudent*>(p);
便无需修改地址就可以操作研究生了,这种reinterpret_cast转换,纯粹是地址不变而指针类型改变,即指针操作的意义改变。但前提是学生对象与研究生对象地址重合。

1. 覆盖父类操作

如果父类中有一个操作,在子类中没有重新定义,则子类可以沿用该操作,但都是父类操作。例如下列程序中,研究生类GraduateStudent继承了Student类,对象gs在显示其本人信息时,没有办法显示相关的研究生信息。这主要是GraduateStudent类中没有重载display成员函数,为了准备使用GraduateStudent类,需要在GraduateStudent类中把父类中的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类对象进行操作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值