?
福建农林大学计算机与信息学院实验报告
系:? ???计算机???? ??专业:?? 计算机科学与技术(专升本) ???年级: 2007级??????????????
姓名:?? 莫小平? ?????学号:?? 071806121?? 实验室号__ 综南附301?? 计算机号? 1?????
实验时间: ??2007.11.20??? 指导教师签字:???????????????????? 成绩:????????????
实验六、继承与派生类
一、???? 实验目的和要求
l???????? 掌握单继承和多继承的概念
l???????? 理解不同的继承类型,掌握使用继承类型的时机
l???????? 掌握派生类中构造函数定义时继承父类构造函数的方法
二、???? 实验内容和原理
实验内容:
设图书馆的图书包含书名、编号和作者属性,读者包含姓名和借书证属性,每位读者最多可借5本书,编写列出某读者的借书情况。
实验原理:
设计一个基类,含有编号和名称,从它派生出图书类和读者类,在读者类中定义用于描述借书的成员函数。建立一个基类libraryrary_object,从它派生出图书类book和读者类reader,两个派生类分别继承了基类相应数据,创建几个构造函数初始化成员,最后在主函数中将book和reader对象进行实例化,显示读者借书的情况。
三、???? 实验环境:
硬件:
CPU: Intel Pentium Dual E2140
硬盘:160G
内存:1G
(3)局域网环境
软件:
Windows XP中文操作系统
Visual C++6.0
四、???? 算法描述及实验步骤:
实现步骤:
1.启动Visual C++开发环境
2.新建程序项目
3.在文件编辑区窗口编写程序代码
4.编译、链接和执行程序
源代码为:
#include<iostream.h>
#include<string.h>
class libraryrary_object?????????????????? //定义一个基类
{
?char name[20];???????????????? //图书名称
?int No;??????????????????????? //图书编号
public:
?library_object(){}????? ?????????????//默认构造函数
?library_object(char na[],int n)
?{
?????strcpy(name,na);No=n;
?}
?void show()
?{
?????cout<<name<<"("<<No<<")";
?}
};
?
class book:public library_object????????? //派生图书类
{
?char author[10];????????????? //图书作者
public:
?book(){}????????????????????? //默认构造函数
?book(char na[],int n,char auth[]):library_object(na,n)
?{
?????strcpy(author,auth);
?}
?void showbook()?????????????? //显示图书函数
?{
?????show();
?????cout<<"作者:"<<author;
?}
};
class reader:public library_object??????? //派生读者类
{
?book rent[5];??????????????? //借书的目录数组,最多借5本
?int top;
public:
?reader(char na[],int n):library_object(na,n){top=0;}
?void rentbook(book &b)?????
?{
????????if (top<5)??????????????? //最多可借5本书
?????????{
???????????rent[top]=b;
???????????top++;
?????????}
?????????else
?????????{
???????????cout<<"对不起,您的图书已经超过5本!"<<endl;
???????????cout<<"无法再借出!"<<endl;
?????????}
?}
?
?void showreader()??????????????????? //显示读者借书情况
?{??
?????cout<<"读者:";
???????show();
?????cout<<endl<<"所借的图书:"<<endl;
?????for(int i=0;i<top;i++)
?????{??
?????????cout<<" "<<i+1<<":";
?????????rent[i].show();
?????????cout<<endl;
?????}
?}
};
void main()
{
?book b1("C++",001,"谭浩强"),
??????b2("photoshop",002,"吴华"),
??????b3("标准日本语",003,"光村"),
??????b4("幻城",004,"郭敬明"),
??????b5("三重门",005,"韩寒"),
??????b6("品三国",006,"易中天");
?reader r1("莫小平",000001);
?r1.rentbook(b1);
?r1.rentbook(b2);
?r1.rentbook(b3);
?r1.rentbook(b4);
?r1.rentbook(b5);
???r1.rentbook(b6);???????? //借第6本书。测试实验是否符合要求
?r1.showreader();
}
五、?????? 调试过程:
在调试过程中,在 ”void library_object()::showbook” 处出错, 因为showbook只是book类的一个函数,而不是直接在library_object下的,虽然book是library_object的派生类,可是下属相关函数却不能越过book与library_object外联定义。之后将 ”void library_object()::showbook” 改成”void book()::showbook” ,问题就解决了:
六、???? 实验结果:
程序点击运行,借出数在5本之内,结果为
当书本借出数超过5本时,
在这边也可以再设一个读者
例如:reader r2("sunshine ",000002);让r2.rentbook(b6);
七、???? 总结:
通过此次实验练习,对单继承和多继承的概念有初步的掌握, 理解了不同的继承类型,对使用继承类型的时机和方法有了一些了解。了解到为了以后不发生混淆,类的直接相关函数应该直接在其类里定义,而不是在函数外定义。
附录:
[1] 谭浩强著.C++面向对象程序设计.北京:清华大学出版社,2006
[2] 谭浩强著.C++面向对象程序设计题解与上机指导.北京:清华大学出版社,2006
?
福建农林大学计算机与信息学院实验报告
系: 计算机??? ???专业: 计算机科学与技术(专升本) ???年级: 2007级??????????????
姓名: 莫小平??? ?学号: 071806121 ????实验室号: 综南附301? ?计算机号: ??1? ??????????
实验时间:? 2007.11.27??? ????指导教师签字: ??????????????????成绩:???????? ????
实验七? 多态和虚函数
一、???? 实验目的和要求
l???????? 掌握多态的概念和实验方法。
l???????? 了解虚函数的作用及使用方法。
二、???? 实验内容和原理
实验内容:
编写一个评选优秀教师和学生的程序,优秀教师的标准是一年内发表论文3篇以上(这边不等于3篇),优秀学生的标准是考试平均成绩在90分以上(不等于90分),当输入一系列的教师和学生的姓名,教师的论文数和学生的分数后,列出优秀教师和学生的名单。
实验原理:
设计一个基类,其中包含描述姓名的数据成员、判定是否优秀的纯虚函数;由此派生出教师类和学生类,教师类中增添表示论文数的数据成员、重载判定是否优秀的成员函数,学生类中增添表示平均成绩的数据成员、重载判定是否是优秀的成员函数。最后主函数输出优秀教师和学生的名单。
三、???? 实验环境
硬件:
CPU: Intel Pentium Dual E2140
硬盘:160G
内存:1G
(3)局域网环境
软件:
Windows XP中文操作系统
Visual C++6.0
四、???? 算法描述及实验步骤
实现步骤:
1.启动Visual C++开发环境
2.新建程序项目
3.在文件编辑区窗口编写程序代码
4.编译、链接和执行程序
源代码为:
#include <iostream.h>
class base????????????????????? ???????????//定义一个基类
{
?????public:
???????virtual void print(){}???????????? //虚函数
???????virtual bool isgood()=0;?????????? //纯虚函数
?????protected:?????????????????????????? //基类保护成员
???????char name[10];
};
class student: public base??????????????? //派生学生类
{
?????public:???????????????????????????? //公有成员
???????void print();?????????????????????
???????void Setname(){cin>>name;}
???????void Setscore(){cin>>score;}
???????virtual bool isgood(){return score>90;}//对虚函数再次定义
?????private:????????? ??????????????????//私有成员
???????int score;
};
?
void student::print()???????????????????? //定义输出函数
{
???????if (isgood()){cout<<"优秀学生:"<<name<<endl;}
}
class teacher: public base?????????????? //派生老师类
{
?????public:??????????????????????????? //公有成员
???????void print();?????????????????????
???????void Setname(){cin>>name;}
???????void Setcount(){cin>>count;}
???????virtual bool isgood(){return count>3;}//对虚函数再次定义
?????private:?????????????????????????? //私有成员
???????int count;
};
?
void teacher::print()????????????????????? //定义输出函数
{
???????if (isgood()){cout<<"优秀老师姓名:"<<name<<endl;}
}
const int sizes=3;??? // sizes是指老师所发表的论文数,这里我把他定义为3篇
?
void main(int argc, char* argv[])
{
student *stud[sizes]; //定义一个指向学生类对象的指针数组变量stud
?teacher *teach[sizes]; //定义一个指向老师类对象的指针数组变量teach
????int counts = 0;
????char fla;
????while (counts<20)? //可以自定义counts的个数
???{
?????cout<<"输入学生名字:";
?????stud[counts]=new student(); //在Stud中存放新建对象的起始地址
?????stud[counts]->Setname();?????
?????cout<<"输入学生成绩:";
?????stud[counts]->Setscore();
?????cout<<"输入老师姓名:";
?????teach[counts]=new teacher();
?????teach[counts]->Setname();
?????cout<<"输入老师发表论文数目:";
?????teach[counts]->Setcount();
?????++counts;
?????cout<<"是否退出? (Y/N) ";
?????cin>>fla;
??????if ( fla == 'y'|| flag== 'Y' ?)? //如果输入y的话就跳出循环
?????????break;
?????}
?????cout<<”********************************************”<<endl;
?????cout<<"优秀教师和学生的名单如下:"<<endl;
?????for(int i=0;i<counts;i++)
?????{
???????stud[i]->print();
???????teach[i]->print();
?????}
?????cout<<endl;
}
?
五、???? 调试过程
在这边只要把main函数的int改为void。在类中声明了纯虚函数,如果在派生类中没有对该函数再次定义,则该需函数在派生类中仍然为纯虚函数,所以在派生学生类和老师类中,需对虚函数进行再次定义,就没问题了。
六、???? 实验结果
七、???? 总结
在这次实验中,熟练地掌握虚函数和纯虚函数的使用方法,了解纯虚函数只有函数的名字而不具备函数的功能,不能被调用。
附录:
[1] 谭浩强著.C++面向对象程序设计.北京:清华大学出版社,2006
[2] 谭浩强著.C++面向对象程序设计题解与上机指导.北京:清华大学出版社,2006
?
系: ???计算机???????? 专业:? 计算机科学与技术(专升本)? ???年级: 2007级??????????????
姓名: ?莫小平??? 学号:?? 071806121?? 实验室号__ 综南附301????? 计算机号? 1?????
实验时间:? 2007.12.4?? ???指导教师签字:?????????????????????? 成绩:????????????
实验八? 运算符重载
一、???????? 实验目的和要求
l?????? 掌握运用成员函数、友元函数实现运算符重载的方法
l?????? 掌握重载运算符函数的调用方法
二、???????? 实验内容和原理
实验内容:设计一个日期类date,其中包含年、月、日等数据成员。要求实现日期的基本运算,如一日期加上天数、或减去天数后的日期,两个日期之间相差的天数。
在date类中实现如下运算符重载函数:
date operator +(int days);
date operator -(int days);
int operator –(date &d);
实验原理:?定义一个日期类date,对运算符进行重载。运算符”+”表示某日期加上若干天后的日期,第一个"-"表示某日期减去若干天后的日期,第二个"-"表示两日期相差的天数。函数leap()判断指定的年份是否为闰年,函数dton()将指定的日期转换成从0年0月0日起的天数,调用函数leap(),函数ntod将指定的某年某月某日起的天数转换成对应的日期。"+"运算符重载时,先将当前日期转换为从某年某月某日起的天数,再加上要加的天数,最后将天数再转换成对应的日期。最后输入日期,通过相关函数计算得到结果.
三、???????? 实验环境:
硬件:
CPU: Intel Pentium Dual E2140
硬盘:160G
内存:1G
(3)局域网环境
软件:
Windows XP中文操作系统
Visual C++6.0
四、???????? 算法描述及实验步骤:
实现步骤:
1.启动Visual C++开发环境
2.新建程序项目
3.在文件编辑区窗口编写程序代码
4.编译、链接和执行程序
源代码为:
#include<iostream>
using namespace std;
int day_tab[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,31,30,31,30,31}};
// day_tab 二维数组存放各月天数,第一行对应非闰年,第二行对应闰年
class Date
{
??int year,month,day;
??int leap(int);
??int dton(Date &);
??Date ntod(int);
?public:
??Date(){};
??Date(int y,int m,int d)
??{
???year=y;month=m;day=d;
??}
??void setday(int d){day=d;}
??void setmonth(int m){month=m;}
??void setyear(int y){year=y;}
??int getday(){return day;}
??int getmonth(){return month;}
??int getyear(){return year;}
?
??Date operator+(int days)
??{
???static Date date;
???int number=dton(*this)+days;
???date=ntod(number);
???return date;
??}
?
??Date operator-(int days)
??{
???static Date date;
???int number=dton(*this);
???number-=days;
???date=ntod(number);
???return date;
??}
?
??int operator-(Date &b)
??{
???int days=dton(*this)-dton(b)-1;
???return days;
??}
?
??void disp()
??{
???cout<<year<<"."<<month<<"."<<day<<endl;
??}
};
?
int Date::leap(int year)
{
??if(year%4==0&&year%100!=0||year%400==0) // 是闰年
??return 1;
??else // 不是闰年
??return 0;
}
?
int Date::dton(Date &d)
{
??int y,m,days=0;
??for(y=1;y<=d.year;y++)
??if(leap(y))
??days+=366;
??else
??days+=365;
??for(m=0;m<d.month-1;m++)
??if(leap(d.year))
??days+=day_tab[1][m];
??else
??days+=day_tab[0][m];
??days+=d.day;
??return days;
}
?
Date Date::ntod(int n)
{
??int y=1,m=1,d,rest=n,lp;
??while(1)
??{
?????if(leap(y))
?????{
???if(rest<=366)
???break;
???else
???rest-=366;
?????}
?????else
????{
???if(rest<=365)
???break;
???else
???rest-=365;
????}
????y++;
?}
????y--;
??lp=leap(y);
?
??while(1)
??{
?????if(lp)
?????{
???if(rest>day_tab[1][m-1])
???rest-=day_tab[1][m-1];
???else
???break