课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565
(第10周学校放春假,空一周)
【目的】1. 掌握类的派生与继承的概念;2. 学会定义子类,重点是类的构造函数与析构函数
第一部分 阅读程序
【程序1】阅读下面的程序,写出程序运行结果,上机时再运行,对比结果是否有差异,仔细领会继承,以及基类、派生类中构造函数的写法及执行过程
#include <iostream> #include <string> using namespace std; class Student//声明基类 { public: //公用部分 Student(int n, string nam ) //基类构造函数,与例.5相同 { num=n; name=nam; } void display( ) //成员函数,输出基类数据成员 { cout<<"num:"<<num<<endl<<"name:"<<name<<endl; } protected: //保护部分 int num; string name; }; class Student1: public Student //声明公用派生类Student1 { public: Student1(int n, string nam,int n1, string nam1,int a, string ad): Student(n,nam),monitor(n1,nam1) //派生类构造函数 { age=a; addr=ad; } void show( ) { cout<<"This student is:"<<endl; display(); //输出num和name cout<<"age: "<<age<<endl; //输出age cout<<"address: "<<addr<<endl<<endl; //输出addr } void show_monitor( ) //成员函数,输出子对象 { cout<<endl<<"Class monitor is:"<<endl; monitor.display( ); //调用基类成员函数 } private: //派生类的私有数据 Student monitor; //定义子对象(班长) int age; string addr; }; int main( ) { Student1 stud1(10010,"Wang-li",10001,"Li-sun",19,"115 Beijing Road,Shanghai"); stud1.show( ); //输出学生的数据 stud1.show_monitor(); //输出子对象的数据 return 0; }
【程序2】先分析程序的执行结果,在上机时运行程序进行对照,再通过单步执行跟踪程序的运行,达到理解基类、派生类中构造函数、析构函数执行过程的目的。
#include <iostream> using namespace std; class Part //部件类 { public: Part(); Part(int i); ~Part(); private: int val; }; class Whole: public Part { public: Whole(); Whole(int,int,int,int); ~Whole(); private: Part one; Part two; int data; }; Part::Part() { val=0; cout<<"The default constructor of part was called "<<val<<endl; } Part::Part(int i) { val=i; cout<<"The constructor of part was called "<<val<<endl; } Part::~Part() { cout<<"The destructor of part was called "<<val<<endl; } Whole::Whole() { data=0; cout<<"The default constructor of whole was called "<<data<<endl; } Whole::Whole(int p, int i,int j,int k):Part(p), two(i),one(j),data(k) { cout<<"The constructor of whole was called "<<data<<endl; } Whole::~Whole() { cout<<"The destructor of whole was called "<<data<<endl; } int main() { Whole w1; Whole w2(1,2,3,4); return 0; } /* 如果用vs2008,将上面的main()函数删除,换作下面的两个函数 void f() { Whole w1; Whole w2(1,2,3,4); } int main() { f(); system("pause"); return 0; } */
第二部分 实践项目
【项目1】定义点类,并以点类为基类,派生出直线类,从基类中继承的点的信息表示直线的中点。请阅读下面的代码,并将缺少的部分写出来。
#include<iostream> #include<Cmath> using namespace std; class Point //定义坐标点类 { public: Point():x(0),y(0) {}; Point(double x0, double y0):x(x0), y(y0) {}; void PrintPoint(); //输出点的信息 double x,y; //数据成员,表示点的横坐标和纵坐标 }; void Point::PrintPoint() { cout<<"Point:("<<x<<","<<y<<")"; //输出点 } class Line: public Point //利用坐标点类定义直线类, 其基类的数据成员表示直线的中点 { public: Line(Point pt1, Point pt2); //构造函数,初始化直线的两个端点及由基类数据成员描述的中点,中点的坐标可以由端点坐标计算而来 double Length(); //计算并返回直线的长度 void PrintLine(); //输出直线的两个端点和直线长度 private: Point pts,pte; //直线的两个端点 }; //下面定义Line类的成员函数 int main() { Point ps(-2,5),pe(7,9); Line l(ps,pe); _____________________;//输出直线l的信息(请补全代码) cout<<"\n The middle point of Line: "; _____________________ ;//输出直线l中点的信息(请补全代码,调用成员函数完成) return 0; }
【项目2】要求与项目1几乎完全相同(除Point类中的数据成员要求为private型),要求补全点类和直线类的定义,调用main()函数输出一条直线的信息。
请不要直接copy项目1的代码,通过修改项目1的程序完成项目2的要求。在有关“抄之有道”的学习方法中,我们有阅读代码,然后自己再写出来的建议。所以,项目2可以在以下代码的提示下开始去做,在项目1中获得的经验会有所帮助,这个过程也会对项目1中的收获有更多理解。其实,当这一些技术熟练之后,根据需求会自己设计并实现,那是我们的最终目标。
项目2可以参考的代码如下,在完成时可以根据需要自行添加其他成员函数,成员函数在类内实现还是类外实现,也可以自行决定。
class Point //定义坐标点类 { public: //定义必要的构造函数 void PrintPoint(); //输出点的信息 private: double x,y; //点的横坐标和纵坐标 }; class Line: public Point //利用坐标点类定义直线类, 其基类的数据成员表示直线的中点 { public: Line(Point pts, Point pte); //构造函数,用初始化直线的两个端点及由基类数据成员描述的中点 void PrintLine(); //输出直线的两个端点和直线长度 private: class Point pts, pte; //直线的两个端点 }; int main() { Point ps(-2,5),pe(7,9); Line l(ps,pe); //下面输出直线l的端点、长度和、中点的信息 return 0; }
【项目3】定义一个名为CPerson的类,有以下私有成员:姓名、身份证号、性别和年龄,成员函数:构造函数、析构函数、输出信息的函数。并在此基础上派生出CEmployee类,派生类CEmployee增加了两个新的数据成员,分别用于表示部门和薪水。要求派生类CEmployee的构造函数显示调用基类CPerson的构造函数,并为派生类CEmployee定义析构函数,定义输出信息的函数。
class CPerson { protected: char *m_szName; char *m_szId; int m_nSex;//0:women,1:man int m_nAge; public: CPerson(char *name,char *id,int sex,int age); void Show1(); ~CPerson(); //需要释放建立对象时动态分配的内存 }; class CEmployee:public CPerson { private: char *m_szDepartment; float m_Salary; public: CEmployee(char *name,char *id,int sex,int age,char *department,float salary); void Show2(); ~CEmployee(); }; int main() { char name[10],id[19],department[10]; int sex,age; float salary; cout<<"input employee's name,id,sex(0:women,1:man),age,department,salary:\n"; cin>>name>>id>>sex>>age>>department>>salary; CEmployee employee1(name,id,sex,age,department,salary); employee1.Show2(); return 0; }
下面的运行结果供参考:
【项目4】按以下的提示,由基类的设计和测试开始,逐渐地完成各个类的设计,并且完成要求的计算任务:
(1)先建立一个Point(点)类,包含数据成员x,y(坐标点);
(2)以Point为基类,派生出一个Circle(圆)类,增加数据成员 (半径);
(3)再以Circle类为直接基类,派生出一个Cylinder(圆柱体)类,再增加数据成员h(高)。
要求编写程序,设计出各类中基本的成员函数(包括构造函数、析构函数、修改数据成员和获取数据成员的公共接口、用于输出的重载运算符“<<”函数等),使之能用于处理以上类对象,最后求出圆格柱体的表面积、体积并输出。
(提示:此任务可以分为三个子任务分成若干步骤进行。先声明基类,再声明派生类,逐级进行,分步调试。——这种方法适用于做任何的项目)