1、 西安交大C++程序设计第十章作业 精品资料 西安交通大学实验报告 课程__计算机程序设计__实验名称__多态性__第 1 页 共 44 页 系 别____ ______ 实 验 日 期 2014 年 5 月 31 日 专业班级__ ____组别_____________ 实 验 报 告 日 期 2014 年 5 月 31 日 姓 名___ _____学号_ _ 报 告 退 发 ( 订正 、 重做 ) 同 组 人________________________
2、 教 师 审 批 签 字
一、实验目的
理解掌握多态的使用方法,学会用虚函数。
二、实验内容
(一)第一题:定义一个类Base,该类含有虚函数display,然后定义它的两个派生类FirstB和SecondB,这两个派生类均含有公有成员函数display,在主程序中,定义指向基类Base的指针变量ptr,并分别定义Base、FirstB、Second的对象b1、f1、s1,让ptr分别指向b1、f1、s1的起始地址,然后指向执行这些对象的成员函数display。
1.源程序代码:
#include
3、std; class Base { public: virtual void display() { cout<<"sound!sound!sound!"; } }; class FirstB:public Base { public: void virtual display() { cout<<"miao!miao!miao!"; } }; class SecondB:public Base { public: void virtual display() { cout<<"wang!wang!wang!"; }
4、
};
int main()
{
Base *ptr;
Base b1;
FirstB f1;
SecondB s1;
cout<<"指向基类Base:\t";
ptr=&b1;
ptr->display();
cout<<"\n指向派生类FirstBase:\t";
ptr=&f1;
ptr->display();
cout<<"\n指向派生类SecondB:\t";
ptr=&s1;
ptr->display();
cout< 5、中派生一个正方形类和圆柱体类,写一个测试程序,输出正方形的面积和圆柱体的体积。
1.源程序代码:
//shape类shape.h文件
#ifndef SHAPE_H
#define SHAPE_H
#include 6、e() const=0;
virtual void Print() const=0;
};
#endif
//point.h点类
#ifndef POINT_H
#define POINT_H
#include 7、 x=a;
y=b;
}
int GetX()
{
return x;
}
int GetY()
{
return y;
}
virtual double Volume() const
{
return 0.0;
}
virtual void PrintShapeName()const
{
cout<<"Point:";
}
virtual void Print()const
{
cout<<'['< 8、fndef CIRCLE_H
#define CIRCLE_H
#include 9、) const
{
return radius;
}
virtual double Area() const
{
return 3.14159*radius*radius;
}
virtual double Volume() const
{
return 0.0;
}
virtual void PrintShapeName() const
{
cout<<"Circle:";
}
void Print() const
{
cout<<"Center=";
Point::Print();
cout<< 10、";Radius="< 11、{
SetLength(l);
SetWidth(w);
}
void SetLength(double l)
{
length=(l>=0?l:0);
}
void SetWidth(double w)
{
width=(w>=0?w:0);
}
double GetLength() const
{
return length;
}
double GetWidth() const
{
return width;
}
virtual double Area() const
{
return l 12、ength*width;
}
virtual double Volume() const
{
return 0.0;
}
virtual void Print() const
{
cout<<"Left Top Vertex=";
Point::Print();
cout<<";Length="< 13、er.h圆柱体类
#ifndef CYLINDER_H
#define CYLINDER_H
#include"circle.h"
#include 14、h>=0?h:0);
}
double GetHeight() const
{
return height;
}
double Volume() const
{
return Area()*height;
}
virtual void PrintShapeName() const
{
cout<<"Cylinder:";
}
void Print() const
{
Circle::Print();
cout<<"Height="< 15、h正方形类,几乎跟矩形类一样而已
#ifndef SQUARE_H
#define Square_H
#include"rectangle.h"
#include 16、 }
virtual double Area() const
{
return sidelength*sidelength;
}
virtual double Volume() const
{
return 0.0;
}
virtual void Print() const
{
cout<<"Left Top Vertex=";
Point::Print();
cout<<";Length="< 17、ut<<"Square:";
}
};
#endif
main.h//要求:派生出圆柱类和正方形类,计算面积、体积
#include 18、irtualViaReference(const Shape&);
int main()
{
//创建point circle rectangular对象信息
Point point(30,50);
Circle circle(120,80,10.0);
Rectangle rectangle(10,10,8.0,5.0);
Square square(10,20,5.0);
Cylinder cylinder(120,80,10.0,40.0);
//输出point circle rectangular 对象信息
point.PrintShapeName( 19、);
point.Print();
cout< 20、
arrayOfShapes[1]=&circle;
arrayOfShapes[2]=&rectangle;
arrayOfShapes[3]=□
arrayOfShapes[4]=&cylinder;
//通过基类对象指针访问派生类对象
cout<<"Virtual function calls made off"<<"base-class pointers\n";
for(int i=0;i<5;i++)
virtualViaPointer(arrayOfShapes[i]);
cout<<"Virtual function calls 21、 made off"<<"base-case references\n";
for(int j=0;j<5;j++)
virtualViaReference(*arrayOfShapes[j]);
return 0;
}
//通过基类对象访问虚函数实现动态绑定???
void virtualViaPointer(const Shape*baseClassPtr)
{
baseClassPtr->PrintShapeName();
baseClassPtr->Print();
cout<<"Area="< 22、<<"\tVolume="< 23、题: 扩充实例编程中的日期类,为Date增加一个成员函数,可以判断日期是否为系统当前日期。从键盘输入你的生日,如果今天是你的生日则显示:“Harry Birthday!”否则显示“还有**天是你的生日”或者“你的生日已经过去了** 天,距离明年生日还有**天”。
1.源程序代码:
// 日期类定义date.h
#ifndef DATE_H
#define DATE_H
#include 24、 DayCalc() const; //距基准日期的天数
static const int days[]; //每月的天数
public:
Date( int y, int m, int d); //构造函数
Date( int m, int d); //构造函数,年默认为系统当前年份
Date(); //构造函数,默认为系统日期
void SystemDate();
void SetDate( int yy, int mm, int dd ); //日期设置
void SetDate( int mm, int dd ); //日期设置,年默认为系统年份
bo 25、ol IsLeapYear(int yy) const; // 是否闰年?
bool IsEndofMonth() const; // 是否月末?
void print_ymd() const; //输出日期yy_mm_dd
void print_mdy() const; //输出日期mm_dd_yy
const Date &operator+(int days); // 日期增加任意天
const Date &operator+=(int days); // 日期增加任意天
int operator-(const Date& ymd)const; // 两个日期之间的 26、天数
void Show(Date& da);
};
#endif
// Date类成员函数定义date.cpp
#include 27、e(int m,int d) { SetDate(m,d); }
Date::Date() {SystemDate();}
void Date::SystemDate()
{ //取得系统日期
tm *gm;
time_t t=time(NULL);
gm = gmtime(&t);
year = 1900 + gm->tm_year;
month = gm->tm_mon +1;
day = gm->tm_mday;
}
void Date::SetDate( int yy, int mm, int dd )
{
month = ( mm >= 1 & 28、 mm <= 12 ) ? mm : 1;
year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900;
if ( month == 2 && IsLeapYear( year ) )
day = ( dd >= 1 && dd <= 29 ) ? dd : 1;
else
day = ( dd >= 1 && dd <= days[ month ] ) ? dd : 1;
}
void Date::SetDate(int mm, int dd )
{
tm *gm;
time_t t=time(NULL);
gm 29、 = gmtime(&t);
month = ( mm >= 1 && mm <= 12 ) ? mm : 1;
year = 1900 + gm->tm_year;
if ( month == 2 && IsLeapYear( year ) )
day = ( dd >= 1 && dd <= 29 ) ? dd : 1;
else
day = ( dd >= 1 && dd <= days[ month ] ) ? dd : 1;
}
const Date &Date::operator+( int days )
{ //重载+
for ( int i 30、 = 0; i < days; i++ )
IncDay();
return *this;
}
const Date &Date::operator+=( int days )
{ //重载+=
for ( int i = 0; i < days; i++ )
IncDay();
return *this;
}
int Date::operator-(const Date& ymd )const
{ //重载-
int days;
days = DayCalc()-ymd.DayCalc();
return days;
}
bool Date 31、IsLeapYear( int y ) const
{
if ( y % 400 == 0 || ( y % 100 != 0 && y % 4 == 0 ) )
return true;
return false;
}
bool Date::IsEndofMonth() const
{
if ( month == 2 && IsLeapYear( year ) )
return day == 29; //二月需要判断是否闰年
else
return day == days[ month ];
}
void Date::IncDay()
{ 32、 //日期递增一天
if ( IsEndofMonth())
if (month == 12){ // 年末
day = 1;
month = 1;
year++;
}
else { // 月末
day = 1;
month++;
}
else day++;
}
int Date::DayCalc() const
{
int dd;
int yy = year - 1900;
dd = yy*365;
if(yy) dd += (yy-1)/4;
for(int i=1; 33、i 34、y", "June",
"July", "August", "September", "October",
"November", "December" };
cout << monthName[ month-1 ] << ' '
<< day << ", " << year << endl;
}
void Date::Show(Date& da)
{
if(day==da.day&&month==da.month)
cout<<"Happy Birthday!";
else
{
if(da-Date::Date()<0)
da.ye 35、ar++;
cout<<"It will be your birthday after "< 36、
Date today,Olympicday(2004,8,13);
cout << "Today (the computer's day) is: ";
today.print_ymd();
cout << "After 365 days, the date is: ";
today += 365;
today.print_ymd();
Date testday(2,28);
cout << "the test date is: ";
testday.print_ymd();
Date nextday = testday + 1;
cout << 37、"the next date is: ";
nextday.print_ymd();
today.SystemDate();
cout << "the Athens Olympic Games openday is: ";
Olympicday.print_mdy();
cout << "And after " << Olympicday-today
<< " days, the Athens Olympic Games will open." < 38、n>>a>>b;
Date birthday(a,b);
today.Show(birthday);
cout< 39、形状。假定方柱体的正方形面积小于圆柱体的圆形面积,注意方柱体的高与正方形的边长不一定相等。再用圆柱体 _ 方柱体蛋糕类派生出圆柱体 _ 方柱体 _ 菱形体蛋糕类,即在方柱体形状上增加菱形柱体形状。假定菱形柱体的菱形面积小于方柱体的正方形面积。提示: ① 运算符 > 重载指两个蛋糕对象的体积大小。 ②基类和派生类数据成员不能定义为 public 。③ 设置数据成员函数、求蛋糕体积、求蛋糕表面积函数、输出生日祝词与蛋糕形状函数均为同名重载函数,例如分别采用函数名为 init() 、 volume() 、 area() 、 output() 。程序运行参考图如下:(红颜色的功能下一章实验完成)
1 40、源程序代码:
//yuan.h圆类头文件
#ifndef YUAN_H
#define YUAN_H
class Yuan
{
int YuanH,YuanR;
char Word[50];
public:
Yuan()
{
YuanH=0;
YuanR=0;
strcpy(Word,"Happy Birthday!");
}
Yuan(int h,int r,char word[])
{
Set(h,r,word);
}
void Set(int h,int r,char word[])
{
YuanH=h; 41、
YuanR=r;
strcpy(Word,word);
}
double Vol()
{
return YuanH*YuanR*YuanR*3.14159;
}
double Area()
{
return 2*(YuanH*YuanR*3.14159+3.14159*YuanR*YuanR);
}
void Print()
{
cout< 42、);
}
Yuan operator >(Yuan& y)
{
if(Vol()>y.Vol())
cout<<"第一个蛋糕大";
if(Vol()==y.Vol())
cout<<"两个蛋糕一样大";
if(Vol() 43、lic Yuan
{
int FangH,FangS;
public:
Yuan_Fang()
{
FangH=0;
FangS=0;
Yuan::Set(0,0,"Happy birthday!");
}
Yuan_Fang(int yuanh,int yuanr,int fangh,int fangs,char word[])
{
Set(yuanh,yuanr,fangh,fangs,word);
}
void Set(int yuanh,int yuanr,int fangh,int fangs,char word[])
44、{
Yuan::Set(yuanh,yuanr,word);
FangH=fangh;
FangS=fangs;
}
double Vol()
{
return Yuan::Vol()+FangH*FangS*FangS;
}
double Area()
{
return 4*FangH*FangS+2*FangS*FangS;
}
double Areato()
{
return Area()+Yuan::Area()-2*FangS*FangS;
}
void Print()
{
Yuan::Prin 45、t();
cout<<"\n方形蛋糕:";
cout<<"高:"< 46、ing.h圆方菱类头文件
#ifndef YUAN_FANG_LING_H
#define YUAN_FANG_LING_H
#include 47、ngH=0;
LingA=0;
LingB=0;
}
Yuan_Fang_Ling(int yuanh,int yuanr,int fangh,int fangs,int lingh,int linga,int lingb,char word[])
{
Set(yuanh,yuanr,fangh,fangs,lingh,linga,lingb,word);
}
void Set(int yuanh,int yuanr,int fangh,int fangs,int lingh,int linga,int lingb,char word[])
{
48、Yuan_Fang::Set(yuanh,yuanr,fangh,fangs,word);
LingH=lingh;
LingA=linga;
LingB=lingb;
}
double Vol()
{
return Yuan_Fang::Vol()+LingH*LingA*LingB/2;
}
double Area()
{
return LingA*LingB+2*LingH*(LingA+LingB);
}
double Areato()
{
return Yuan_Fang::Areato()+Area()-Lin 49、gA*LingB;
}
void Print()
{
Yuan_Fang::Print();
cout<<"\n菱形蛋糕:";
cout<<" 高:"< 50、g& yfl)
{
if(Vol()>yfl.Vol())
cout<<"第一个蛋糕大";
if(Vol()==yfl.Vol())
cout<<"两个蛋糕一样大";
if(Vol()






