山东科技大学2020年5月11日作业题解
**题目一:**学生干部虚基类
Description
基于Student(学生)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类Student_Cadre(学生兼干部)。
这两个基类均继承自Person类,包含姓名、年龄、性别、地址、电话等数据成员。在Student类中还包含数据成员major(专业),在Cadre类中还包含数据成员post(职务),
在Student_Cadre类中还包含数据成员wages(工资)。
注意使用虚基类使Student_Cadre只包含一份从Person类继承来的成员。
Input
学生干部的姓名,年龄,性别,专业,职位,地址,电话,薪水
修改该学生干部的新地址,新电话
Output
学生干部的信息
Sample Input
wangli
23
f
BeijingRoad
0532-61234567
software
president
1534.2
Taidonglu
0532-90827651
0531-28766143
Sample Output
name:wangli
age23
sex:f
address:BeijingRoad
tel:0532-61234567
major:software
post:president
wages:1534.2name:wangli
age23
sex:f
address:Taidonglu
tel:0531-28766143
major:software
post:president
wages:1534.2
题目给定代码
int main( )
{
string name, major, post, addr, tel;
int age;
char sex;
float wage;
cin>>name>>age>>sex>>addr>>tel>>major>>post>>wage;
Student_Cadre st_ca(name, age, sex, addr, tel, major, post,wage);
st_ca.display( );
cout<<endl;
string newAddr, newTel1, newTel2;
cin>>newAddr>>newTel1>>newTel2;
st_ca.setAddr(newAddr);
st_ca.Student::setTel(newTel1);
st_ca.Cadre::setTel(newTel2);
st_ca.display( );
return 0;
}
标程
#include<map>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iterator>
#include<iostream>
#include<algorithm>
#define R register
#define LL long long
#define pi 3.141
#define INF 1400000000
using namespace std;
class Person{
protected:
string name, address, tel, major, post;
int age;
char sex;
float wages;
};
class Student : virtual public Person{
public:
void setTel(string s){
tel = s;
}
Student(string a, int b, char c, string d, string e, string f, string g, float h){
name = a, age = b, sex = c, address = d, tel = e, major = f, post = g, wages = h;
}
};
class Cadre : virtual public Person{
public:
void setTel(string s){
tel = s;
}
};
class Student_Cadre : public Student, public Cadre{
public:
Student_Cadre(string a, int b, char c, string d, string e, string f, string g, float h) : Student(a, b, c, d, e, f, g, h){
}
void display(){
cout << "name:" << name << "\nage" << age << "\nsex:" << sex << "\naddress:" << address << "\ntel:" << tel << "\nmajor:" << major << "\npost:" << post << "\nwages:" << wages << "\n";
}
void setAddr(string s){
address = s;
}
};
int main( )
{
string name, major, post, addr, tel;
int age;
char sex;
float wage;
cin>>name>>age>>sex>>addr>>tel>>major>>post>>wage;
Student_Cadre st_ca(name, age, sex, addr, tel, major, post,wage);
st_ca.display( );
cout<<endl;
string newAddr, newTel1, newTel2;
cin>>newAddr>>newTel1>>newTel2;
st_ca.setAddr(newAddr);
st_ca.Student::setTel(newTel1);
st_ca.Cadre::setTel(newTel2);
st_ca.display( );
return 0;
}
**题目二:**又是形状!
Description
从点类分别继承出圆类Circle和矩形类Rectangle,圆可认为是点的基础上增加半径radius,矩形可认为是点的基础上增加长length和宽width(只需考虑横平竖直的矩形)
要求为Circle增加
1)构造函数,
2)成员函数setRadius(double)和double getRadius(),
3)成员函数 int loate(Point t) 判断参数t是在圆内(1)圆外(-1)还是圆上(0),
4)void crossPoints(Point src, Point& cp1, Point& cp2)输出参数t与圆心相连的直线与圆的两个交点(cp1,cp2)。不需考虑该点和中心重叠的情况
为Rectangle增加
- 构造函数,
2)成员函数setHeight(double),setWidth(double)和double getHeight, double getWidth(),
3)成员函数 int locate(Point t) 判断参数t是在矩形内(1)矩形外(-1)还是矩形上(0),
4)成员函数 void crossPoints(Point src, Point& cp1, Point& cp2)输出参数t与矩形中心相连的直线与矩形的两个交点(cp1,cp2)。不需考虑该点和中心重叠的情况
交点输出按照x1<=x2 或者 x1==x2 y1<=y2的顺序
Input
见append.cc
Output
Sample Input
2 2 2
2 0
1 2
0 0
2 0
2 2 6 4
8 6
3 4
2 7
8 7
Sample Output
点p1在圆c1之上
点p2在圆c1之内
点p3在圆c1之外点p1与圆c1的圆心相连,与圆交于两点,分别是:
交点: [2,0]
交点: [2,4]点p1在矩形r1之上
点p2在矩形r1之内
点p3在矩形r1之外点p1与矩形r1的中心相连,与矩形交于两点,分别是:
交点: [3,2]
交点: [7,6]
题目给定代码
int main( )
{
double x,y,r,w,h;
cin>>x>>y>>r;
Circle c1(x,y,r);
cin>>x>>y;
Point p1(x,y);
cout<<"点p1在圆c1之"<<((c1.locate(p1)>0)?"内":((c1.locate(p1)<0)?"外":"上"))<<endl;
cin>>x>>y;
Point p2(x,y);
cout<<"点p2在圆c1之"<<((c1.locate(p2)>0)?"内":((c1.locate(p2)<0)?"外":"上"))<<endl;
cin>>x>>y;
Point p3(x,y);
cout<<"点p3在圆c1之"<<((c1.locate(p3)>0)?"内":((c1.locate(p3)<0)?"外":"上"))<<endl;
cout<<endl;
Point p4,p5;
cin>>x>>y;
p1.setX(x);
p1.setY(y);
c1.crossPoints(p1, p4, p5);
cout<<"点p1与圆c1的圆心相连,与圆交于两点,分别是:"<<endl;
cout<<"交点: "<<p4;
cout<<"交点: "<<p5;
cout<<endl;
cin>>x>>y>>w>>h;
Rectangle r1(x,y,w,h);
cin>>x>>y;
p1.setX(x);
p1.setY(y);
cout<<"点p1在矩形r1之"<<((r1.locate(p1)>0)?"内":((r1.locate(p1)<0)?"外":"上"))<<endl;
cin>>x>>y;
p2.setX(x);
p2.setY(y);
cout<<"点p2在矩形r1之"<<((r1.locate(p2)>0)?"内":((r1.locate(p2)<0)?"外":"上"))<<endl;
cin>>x>>y;
p3.setX(x);
p3.setY(y);
cout<<"点p3在矩形r1之"<<((r1.locate(p3)>0)?"内":((r1.locate(p3)<0)?"外":"上"))<<endl;
cout<<endl;
cin>>x>>y;
p1.setX(x);
p1.setY(y);
r1.crossPoints(p1, p4, p5);
cout<<"点p1与矩形r1的中心相连,与矩形交于两点,分别是:"<<endl;
cout<<"交点: "<<p4;
cout<<"交点: "<<p5;
return 0;
}
标程
#include<map>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iterator>
#include<iostream>
#include<algorithm>
#define R register
#define LL long long
#define pi 3.141
#define INF 1400000000
using namespace std;
double pow(double number) {
return number * number;
}
class Point {
public:
double x, y;
public:
Point() {
}
Point(double a, double b) {
x = a, y = b;
}
void setX(double number) {
x = number;
}
void setY(double number) {
y = number;
}
friend ostream& operator<<(ostream& os, const Point& app) {
os << "[" << app.x << "," << app.y << "]\n";
return os;
}
};
class Circle : public Point {
private:
double x, y, r;
public:
Circle(double a, double b, double c) : Point(x, y){
x = a, y = b, r = c;
}
int locate(Point t) {
if (pow(x - t.x) + pow(y - t.y) == pow(r)) {
return 0;
}
else if (pow(x - t.x) + pow(y - t.y) > pow(r)) {
return -1;
}
return 1;
}
void crossPoints(Point src, Point& cp1, Point& cp2) {
double k;
double x1, y1, x2, y2;
if (src.x != x)
{
k = (src.y - y) / (src.x - x);
x1 = x + r / sqrt(k * k + 1);
x2 = x - r / sqrt(k * k + 1);
y1 = k * (x1 - x) + y;
y2 = k * (x2 - x) + y;
if (x1 < x2)
{
cp1.x = x1;
cp1.y = y1;
cp2.x = x2;
cp2.y = y2;
}
else if (x1 == x2)
{
cp1.x = cp2.x = x1;
if (y1 <= y2)
{
cp1.y = y1;
cp2.y = y2;
}
else
{
cp1.y = y2;
cp2.y = y1;
}
}
else
{
cp1.x = x2;
cp1.y = y2;
cp2.x = x1;
cp2.y = y1;
}
}
else
{
cp1.x = cp2.x = x;
cp1.y = y - r;
cp2.y = y + r;
}
}
};
class Rectangle :public Point
{
private:
double h, w;
public:
Rectangle(double xx, double yy, double ww, double hh) :Point(xx, yy), w(ww), h(hh)
{}
void setHeight(double hh)
{
h = hh;
}
void setWidth(double ww)
{
w = ww;
}
double getHeight()
{
return h;
}
double getWidth()
{
return w;
}
int locate(Point t)
{
double ll = t.x - x;
double hh = t.y - y;
if (0 < ll && ll < w && 0 < hh && hh < h)
return 1;
else if ((ll == 0 || ll == w) && (hh >= 0 && hh <= h) || (ll >= 0 && ll <= w) && (hh == 0 || hh == h))
return 0;
else
return -1;
}
void crossPoints(Point src, Point& cp1, Point& cp2)
{
double k0, k;
double x1, x2, y1, y2;
k0 = h / w;
if (src.x != (x + w / 2))
{
k = (src.y - y - h / 2) / (src.x - x - w / 2);
if (k > k0 || k < -1 * k0)
{
x1 = x + w / 2 - h / (2 * k);
y1 = y;
x2 = x + w / 2 + h / (2 * k);
y2 = y + h;
}
else if (k < k0 || k >= -1 * k0)
{
y1 = y + h / 2 - w * k / 2;
x1 = x;
y2 = y + h / 2 + w * k / 2;
x2 = x + w;
}
if (x1 < x2)
{
cp1.x = x1;
cp1.y = y1;
cp2.x = x2;
cp2.y = y2;
}
else if (x1 == x2)
{
cp1.x = cp2.x = x1;
if (y1 <= y2)
{
cp1.y = y1;
cp2.y = y2;
}
else
{
cp1.y = y2;
cp2.y = y1;
}
}
else
{
cp1.x = x2;
cp1.y = y2;
cp2.x = x1;
cp2.y = y1;
}
}
else
{
cp1.x = cp2.x = x + w / 2;
cp1.y = y;
cp2.y = y + h;
}
}
};
int main( )
{
double x,y,r,w,h;
cin>>x>>y>>r;
Circle c1(x,y,r);
cin>>x>>y;
Point p1(x,y);
cout<<"点p1在圆c1之"<<((c1.locate(p1)>0)?"内":((c1.locate(p1)<0)?"外":"上"))<<endl;
cin>>x>>y;
Point p2(x,y);
cout<<"点p2在圆c1之"<<((c1.locate(p2)>0)?"内":((c1.locate(p2)<0)?"外":"上"))<<endl;
cin>>x>>y;
Point p3(x,y);
cout<<"点p3在圆c1之"<<((c1.locate(p3)>0)?"内":((c1.locate(p3)<0)?"外":"上"))<<endl;
cout<<endl;
Point p4,p5;
cin>>x>>y;
p1.setX(x);
p1.setY(y);
c1.crossPoints(p1, p4, p5);
cout<<"点p1与圆c1的圆心相连,与圆交于两点,分别是:"<<endl;
cout<<"交点: "<<p4;
cout<<"交点: "<<p5;
cout<<endl;
cin>>x>>y>>w>>h;
Rectangle r1(x,y,w,h);
cin>>x>>y;
p1.setX(x);
p1.setY(y);
cout<<"点p1在矩形r1之"<<((r1.locate(p1)>0)?"内":((r1.locate(p1)<0)?"外":"上"))<<endl;
cin>>x>>y;
p2.setX(x);
p2.setY(y);
cout<<"点p2在矩形r1之"<<((r1.locate(p2)>0)?"内":((r1.locate(p2)<0)?"外":"上"))<<endl;
cin>>x>>y;
p3.setX(x);
p3.setY(y);
cout<<"点p3在矩形r1之"<<((r1.locate(p3)>0)?"内":((r1.locate(p3)<0)?"外":"上"))<<endl;
cout<<endl;
cin>>x>>y;
p1.setX(x);
p1.setY(y);
r1.crossPoints(p1, p4, p5);
cout<<"点p1与矩形r1的中心相连,与矩形交于两点,分别是:"<<endl;
cout<<"交点: "<<p4;
cout<<"交点: "<<p5;
return 0;
}
**题目三:**立体空间中的点(I)
Description
设计一个平面上的点Point类和3维的点Point_3D类,满足Point_3D类继承自Point类,用于读取输入的数据,输出所构造的两种点的坐标。
设计Point类需支持一下操作:
Point::Point()无参构造。
Point::Point(double,double)两个坐标参数构造。
Point::showPoint()按格式输出Point对象
设计Point_3D类需支持一下操作:
Point_3D::Point_3D()无参构造。
Point_3D::Point_3D(double,double,double)三个坐标参数构造。
Point_3D::showPoint()按格式输出Point_3D对象。
你设计Point类和Point_3D类,使得main()函数能够正确运行。
函数调用格式见append.cc。
append.cc中已给出main()函数。
Input
输入的第一个整数n,表示有n组测试数据,后面的输入每行为一组测试数据。每组测试数据的第一行是一个整数m,m有两种取值:2、3;m为2时,后面有两个浮点数x、y,表示一个平面上的点的坐标(x,y);m为3时后面有3个浮点数x、y、z,表示一个3维的点的坐标(x,y,z)。
Output
每组测试数据对应一行输出。
若输入为平面上的点,则输出:“2D Point (x,y)”,x和y为输入的坐标值。
若输入为3维的点,则输出:“3D Point (x,y,y)”,x、y和z为输入的坐标值。
Sample Input
5
3 1 2 3
3 0 0 0
2 -1 1
3 -1 -1 -1
2 0 0
Sample Output
3D Point (1,2,3)
3D Point (0,0,0)
2D Point (-1,1)
3D Point (-1,-1,-1)
2D Point (0,0)
题目给定代码
int main()
{
int cases;
cin>>cases;
for(int i = 1; i <= cases; i++)
{
double x, y, z;
int point_type;
cin>>point_type;
if(point_type == 2)
{
cin>>x>>y;
Point p(x, y);
p.showPoint();
}
if(point_type == 3)
{
cin>>x>>y>>z;
Point_3D p(x, y, z);
p.showPoint();
}
}
}
标程
#include<iostream>
#include<set>
#include<iterator>
#include<string>
#include<set>
#include<queue>
#include<list>
#include<algorithm>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<map>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<sstream>
using namespace std;
class Point
{
protected:
int x,y;
public:
Point():x(0),y(0){}
Point(double a,double b):x(a),y(b){}
void showPoint(){cout<<"2D Point ("<<x<<","<<y<<")"<<endl;}
};
class Point_3D:public Point
{
protected:
int z;
public:
Point_3D():z(0){}
Point_3D(double a,double b,double c):Point(a,b),z(c){}
void showPoint(){cout<<"3D Point ("<<x<<","<<y<<","<<z<<")"<<endl;}
};
int main()
{
int cases;
cin>>cases;
for(int i = 1; i <= cases; i++)
{
double x, y, z;
int point_type;
cin>>point_type;
if(point_type == 2)
{
cin>>x>>y;
Point p(x, y);
p.showPoint();
}
if(point_type == 3)
{
cin>>x>>y>>z;
Point_3D p(x, y, z);
p.showPoint();
}
}
}
**题目四:**时间类的拷贝和整体读写
Description
封装一个时间类Time,用于时间处理的相关功能,支持以下操作:
- Time::Time()无参构造方法。
- Time::Time(int,int,int)构造方法:传递时分秒的三个参数构造对象。
- Time::Time(const T&)拷贝构造方法。拷贝构造函数调用时输出“There was a call to the copy constructor : h,m,s”,“h,m,s”为所构造对象的时分秒数值,无需补0。
- 对象整体读写方法:
Time::setTime(int,int,int)方法:传递时分秒三个参数修改Time对象的时分秒数。该方法返回修改后的对象。
Time::setTime(const T&)方法:传递一个参数修改Time对象的时分秒数。该方法返回修改后的对象。
Time::getTime()方法:返回对象自身的引用。其实,t.getTime()即t。
仅在Time类中的Time::getTime()方法实在是多余,在组合或者继承关系时才会有机会用到。 - Time::showTime()方法:输出“hh:mm:ss”,不足两位的要前面补0。
注意:在用Time对象传递参数时应传对象的引用而不是直接传对象,返回对象时同样返回引用,以免产生多余的对象拷贝。
你设计一个时间类Time,使得main()函数能够正确运行。
函数调用格式见append.cc。
append.cc中已给出main()函数。main()函数内容稍微繁复,仅为测试对象的各种调用情况。
Input
输入的第一个整数n,表示有n组测试数据,每组3个整数:hh,mm,ss,分别表示时、分、秒,其值都在合法的时间范围内。
Output
开始部分为由main()函数产生的固定输出,用于测试对象的某些方法的调用情况。输出“Test data output :”之后为测试数据对应的输出:
每组测试数据对应一组输出“hh:mm:ss”,不足两位的输出需要前面补0,格式见sample。
Sample Input
5
0 0 1
0 59 59
1 1 1
23 0 0
23 59 59
Sample Output
Copy constructor test output :
There was a call to the copy constructor : 0,0,0
There was a call to the copy constructor : 1,2,3Test data output :
00:00:01
00:59:59
01:01:01
23:00:00
23:59:59
HINT
输出格式用头文件中流操作算子:
setw(w) :设置数据的输出宽度为w个字符
setfill©:设置用字符c作为填充字符
题目给定代码
int main()
{
cout<<"Copy constructor test output :"<<endl;
Time t;
Time tt(t);
Time ttt(1, 2, 3);
Time tttt(ttt.getTime());
cout<<"\nTest data output :"<<endl;
int cases;
cin>>cases;
for(int i = 1; i <= cases; ++i)
{
if(i % 2 == 0)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.setTime(hour, minute, second).showTime();
}
if(i % 2 == 1)
{
int hour, minute, second;
cin>>hour>>minute>>second;
Time tt(hour, minute, second);
t.setTime(tt).showTime();
}
}
}
标程
#include<iostream>
#include<iomanip>
using namespace std;
class Time
{
private:
int x,y,z;
public:
Time():x(0),y(0),z(0){}
Time(int a,int b,int c):x(a),y(b),z(c){}
Time(const Time &q):x(q.x),y(q.y),z(q.z){cout<<"There was a call to the copy constructor : "<<x<<","<<y<<","<<z<<endl;}
Time &setTime(int a,int b,int c){x=a;y=b;z=c;return *this;}
Time &setTime(const Time &q){x=q.x;y=q.y;z=q.z;return *this;}
Time &getTime(){return *this;}
void showTime(){cout<<setw(2)<<setfill('0')<<x<<":"<<setw(2)<<setfill('0')<<y<<":"<<setw(2)<<setfill('0')<<z<<endl;}
};
int main()
{
cout<<"Copy constructor test output :"<<endl;
Time t;
Time tt(t);
Time ttt(1, 2, 3);
Time tttt(ttt.getTime());
cout<<"\nTest data output :"<<endl;
int cases;
cin>>cases;
for(int i = 1; i <= cases; ++i)
{
if(i % 2 == 0)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.setTime(hour, minute, second).showTime();
}
if(i % 2 == 1)
{
int hour, minute, second;
cin>>hour>>minute>>second;
Time tt(hour, minute, second);
t.setTime(tt).showTime();
}
}
}
**题目五:**时间类的错误数据处理
Description
封装一个时间类Time,用于时间处理的相关功能,支持以下操作:
- Time::Time()无参构造方法。
- Time::Time(int,int,int)构造方法:传递时分秒的三个参数构造对象。
- Time::Time(const T&)拷贝构造方法。
- 成员读函数:
Time::hour() :返回Time的小时数;
Time::minute():返回Time的分钟数;
Time::second():返回Time的秒数。 - 成员写函数:
Time::hour(int) :传参修改Time的小时数;
Time::minute(int):传参修改Time的分钟数;
Time::second(int):传参修改Time的秒数。 - 对象整体读写方法:
Time::setTime(int,int,int)方法:传递时分秒三个参数修改Time对象的时分秒数。该方法返回修改后的对象。
Time::setTime(const T&)方法:传递一个参数修改Time对象的时分秒数。该方法返回修改后的对象。
Time::getTime()方法:返回对象自身的引用。其实,t.getTime()即t。
仅在Time类中的Time::getTime()方法实在是多余,在组合或者继承关系时才会有机会用到。 - Time::inputTime()方法:按格式从标准输入读取数据修改Time对象的时分秒数值。该方法返回修改后的对象。
- Time::showTime()方法:输出“hh:mm:ss”,不足两位的要前面补0。如果对象不是合法的时间,则输出“Time error”。
你设计一个时间类Time,使得main()函数能够正确运行。
函数调用格式见append.cc。
append.cc中已给出main()函数。main()函数内容稍微繁复,仅为测试对象的各种调用情况。
Input
输入的第一个整数n,表示有n组测试数据,每组3个整数:hh,mm,ss,分别表示时、分、秒,其值都在int范围内。
Output
每组测试数据对应一组输出“hh:mm:ss”,不足两位的输出需要前面补0。如果输入的时间不合法,则输出“Time error”。格式见sample。
Sample Input
6
0 0 1
0 59 59
1 1 60
23 0 0
23 59 59
24 1 0
Sample Output
00:00:01
00:59:59
Time error
23:00:00
23:59:59
Time error**
HINT
输出格式用头文件中流操作算子:
setw(w) :设置数据的输出宽度为w个字符
setfill©:设置用字符c作为填充字符
题目给定代码
int main()
{
Time t;
int cases;
cin>>cases;
for(int i = 1; i <= cases; ++i)
{
if(i % 4 == 0)
{
int hour, minute, second;
cin>>hour>>minute>>second;
Time tt(hour, minute, second);
tt.showTime();
}
if(i % 4 == 1)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.setTime(hour, minute, second).showTime();
}
if(i % 4 == 2)
t.inputTime().showTime();
if(i % 4 == 3)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.hour(hour);
t.minute(minute);
t.second(second);
t.showTime();
}
}
}
标程
#include <iostream>
#include <iomanip>
using namespace std;
class Time
{
private:
int h,m,s;
public:
Time():h(0),m(0),s(0){}
Time(int hh,int mm,int ss) : h(hh),m(mm),s(ss){}
Time(const Time &t)
{
h = t.h;m = t.m;s = t.s;
}
public:
Time &setTime(int hh ,int mm ,int ss)
{
h = hh;m = mm;s = ss;
return* this;
}
Time &setTime(const Time & t)
{
h = t.hour();
m = t.minute();
s = t.second();
return *this;
}
Time &getTime()
{
return *this;
}
public:
Time &inputTime()
{
int hour, minute, second;
cin>>hour>>minute>>second;
this->hour(hour);this->minute(minute);this->second(second);
return *this;
}
public:
int hour(int hh){return h = hh;}
int minute(int mm){return m = mm;}
int second(int ss ){return s = ss;}
public:
int hour()const{return h;}
int minute()const{return m;}
int second()const{return s;}
public:
void showTime() const
{
if(h >= 0&& h<24 && m >=0 && m < 60 && s >= 0 && s < 60){
cout << setw(2) << setfill('0');
cout << setw(2) << h << ":";
cout << setw(2) << m << ":";
cout << setw(2) << s << endl;
}
else
cout << "Time error" << endl;
}
};
int main()
{
Time t;
int cases;
cin>>cases;
for(int i = 1; i <= cases; ++i)
{
if(i % 4 == 0)
{
int hour, minute, second;
cin>>hour>>minute>>second;
Time tt(hour, minute, second);
tt.showTime();
}
if(i % 4 == 1)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.setTime(hour, minute, second).showTime();
}
if(i % 4 == 2)
t.inputTime().showTime();
if(i % 4 == 3)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.hour(hour);
t.minute(minute);
t.second(second);
t.showTime();
}
}
}
**题目六:**时间类的常量
Description
封装一个时间类Time,用于时间处理的相关功能,支持以下操作:
- Time::Time()无参构造方法。
- Time::Time(int,int,int)构造方法:传递时分秒的三个参数构造对象。
- Time::Time(const T&)拷贝构造方法。
- 成员读函数:
Time::hour() :返回Time的小时数;
Time::minute():返回Time的分钟数;
Time::second():返回Time的秒数。 - 成员写函数:
Time::hour(int) :传参修改Time的小时数;
Time::minute(int):传参修改Time的分钟数;
Time::second(int):传参修改Time的秒数。 - 对象整体读写方法:
Time::setTime(int,int,int)方法:传递时分秒三个参数修改Time对象的时分秒数。该方法返回修改后的对象。
Time::setTime(const T&)方法:传递一个参数修改Time对象的时分秒数。该方法返回修改后的对象。
Time::getTime()方法:返回对象自身的引用。其实,t.getTime()即t。
仅在Time类中的Time::getTime()方法实在是多余,在组合或者继承关系时才会有机会用到。 - Time::inputTime()方法:按格式从标准输入读取数据修改Time对象的时分秒数值。该方法返回修改后的对象。
- Time::showTime()方法:输出“hh:mm:ss”,不足两位的要前面补0。如果对象不是合法的时间,则输出“Time error”。
注意:为了保证Time类的常量对象能够正确的调用Time类的方法,那些不修改对象数据成员的函数都应该是常量成员函数,在返回对象自身的引用时也应返回常量引用。
你设计一个时间类Time,使得main()函数能够正确运行。
函数调用格式见append.cc。
append.cc中已给出main()函数。main()函数内容稍微繁复,仅为测试对象的各种调用情况。
Input
输入的第一个整数n,表示有n组测试数据,每组3个整数:hh,mm,ss,分别表示时、分、秒,其值都在int范围内。
Output
开始部分为由main()函数产生的固定输出,用于测试对象的某些方法的调用情况。输出“Test data output :”之后为测试数据对应的输出:
每组测试数据对应一组输出“hh:mm:ss”,不足两位的输出需要前面补0。如果输入的时间不合法,则输出“Time error”。格式见sample。
Sample Input
6
0 0 1
0 59 59
1 1 60
23 0 0
23 59 59
24 1 0
Sample Output
Constant test output :
00:00:00
01:02:03
Time errorTest data output :
00:00:01
00:59:59
Time error
23:00:00
23:59:59
Time error
HINT
输出格式用头文件中流操作算子:
setw(w) :设置数据的输出宽度为w个字符
setfill©:设置用字符c作为填充字符
题目给定代码
int main()
{
cout<<"Constant test output :"<<endl;
const Time c;
const Time cc(1, 2, 3);
const Time ccc(23, 60, 60);
cout<<setw(2)<<setfill('0')<<c.hour()<<":";
cout<<setw(2)<<setfill('0')<<c.minute()<<":";
cout<<setw(2)<<setfill('0')<<c.second()<<endl;
cc.getTime().showTime();
ccc.showTime();
cout<<"\nTest data output :"<<endl;
Time t;
int cases;
cin>>cases;
for(int i = 1; i <= cases; ++i)
{
if(i % 4 == 0)
{
int hour, minute, second;
cin>>hour>>minute>>second;
Time tt(hour, minute, second);
tt.showTime();
}
if(i % 4 == 1)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.setTime(hour, minute, second).showTime();
}
if(i % 4 == 2)
t.inputTime().showTime();
if(i % 4 == 3)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.hour(hour);
t.minute(minute);
t.second(second);
t.showTime();
}
}
}
标程
#include<iostream>
#include<iomanip>
using namespace std;
class Time
{
private:
int x,y,z;
public:
Time():x(0),y(0),z(0){}
Time(int a,int b,int c):x(a),y(b),z(c){}
Time(const Time &q):x(q.x),y(q.y),z(q.z){}//cout<<"There was a call to the copy constructor : "<<x<<","<<y<<","<<z<<endl;}
int hour ()const{return x;}
int minute()const{return y;}
int second()const{return z;}
void hour(int a){x=a;}
void minute(int a){y=a;}
void second(int a){z=a;}
Time &setTime(int a,int b,int c){x=a;y=b;z=c;return *this;}
Time &setTime(const Time &q){x=q.x;y=q.y;z=q.z;return *this;}
const Time &getTime()const{return *this;}
Time &inputTime()
{
int a,b,c;
cin>>a>>b>>c;
x=a;y=b;z=c;
return *this;
}
void showTime()const{
if(x<24&&x>=0&&y>=0&&y<60&&z>=0&&z<60)
cout<<setw(2)<<setfill('0')<<x<<":"<<setw(2)<<setfill('0')<<y<<":"<<setw(2)<<setfill('0')<<z<<endl;
else
cout<<"Time error"<<endl;
}
};
int main()
{
cout<<"Constant test output :"<<endl;
const Time c;
const Time cc(1, 2, 3);
const Time ccc(23, 60, 60);
cout<<setw(2)<<setfill('0')<<c.hour()<<":";
cout<<setw(2)<<setfill('0')<<c.minute()<<":";
cout<<setw(2)<<setfill('0')<<c.second()<<endl;
cc.getTime().showTime();
ccc.showTime();
cout<<"\nTest data output :"<<endl;
Time t;
int cases;
cin>>cases;
for(int i = 1; i <= cases; ++i)
{
if(i % 4 == 0)
{
int hour, minute, second;
cin>>hour>>minute>>second;
Time tt(hour, minute, second);
tt.showTime();
}
if(i % 4 == 1)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.setTime(hour, minute, second).showTime();
}
if(i % 4 == 2)
t.inputTime().showTime();
if(i % 4 == 3)
{
int hour, minute, second;
cin>>hour>>minute>>second;
t.hour(hour);
t.minute(minute);
t.second(second);
t.showTime();
}
}
}
**题目七:**让动物们叫起来吧!
Description
Tom家里养了很多动物,比如有鸭子、火鸡和公鸡。它们的叫声都不相同。现在,请编写类Animal、Cock、Turkey和Duck,根据给出的main()函数及样例分析每个类的属性、行为及相互关系,以模仿Tom家的情况。
提示:动物们都有自己的名字。
Input
输入有多行。第一行正整数M表示之后有M个测试用例,每个测试用例包括2部分:前一部分是动物的名字,后一部分是动物的类型(用A、B、C分别表示鸭子、火鸡和公鸡)。
Output
输出有M行,每个测试用例对应一样。见样例。
Sample Input
3
Baby C
Rubby B
Tobby A
Sample Output
Baby is a cock, and it can crow.
Rubby is a turkey, and it can gobble.
Tobby is a duck, and it can quack.
题目给定代码
int main()
{
int cases;
string name;
char type;
Animal *animal;
cin>>cases;
for (int i = 0; i < cases; i++)
{
cin>>name>>type;
switch(type)
{
case 'A':
animal = new Duck(name);
break;
case 'B':
animal = new Turkey(name);
break;
case 'C':
animal = new Cock(name);
break;
}
animal->sound();
}
return 0;
}
标程
#include <iostream>
#include <iomanip>
using namespace std;
class Animal
{
protected:
string name;
public:
virtual void sound()const = 0;
public:
Animal(){ }
Animal(string n) : name(n){ }
virtual ~Animal(){ }
};
class Cock : virtual public Animal
{
public:
void sound() const
{
cout << name << " is a cock, and it can crow." << endl;
}
public:
Cock(string n) : Animal(n){ }
~Cock(){ }
};
class Turkey : virtual public Animal
{
public:
void sound() const
{
cout << name << " is a turkey, and it can gobble." << endl;
}
public:
Turkey(string n) : Animal(n){ }
~Turkey(){ }
};
class Duck : virtual public Animal
{
public:
void sound() const
{
cout << name << " is a duck, and it can quack." << endl;
}
public:
Duck(string n) : Animal(n){ }
~Duck(){ }
};
int main()
{
int cases;
string name;
char type;
Animal *animal;
cin>>cases;
for (int i = 0; i < cases; i++)
{
cin>>name>>type;
switch(type)
{
case 'A':
animal = new Duck(name);
break;
case 'B':
animal = new Turkey(name);
break;
case 'C':
animal = new Cock(name);
break;
}
animal->sound();
}
return 0;
}
**题目八:**薪酬计算 之二
Description
某公司有经理(Manager)、销售(Sales)、销售经理(SalesManager)四类雇员(Employee),他们的薪酬计算方法各不一样:
每个雇员(Employee)都有每月的基本工资;
经理(Manager)除了基本工资之外还有年终分红;
销售(Sales)除了基本工资之外,每月还有营销提成;
销售经理(SalesManager)既是销售(Sales)人员也是经理(Manager),因此他既有每月的营销提成,也有年终分红。
每类雇员的年薪计算方式不一样,因此使用多态来实现。
请仔细阅读append.cc代码,并设计并实现这个员工类的派生体系,使main()函数能够运行并得到正确的输出。
Input
输入第一个整数n,表示后面有n个雇员。每个雇员占用一行输入。分别是员工类型、姓名、月基本工资、月营销提成(销售)、年终分红(经理),如果是销售经理则两者都有。
Output
从输入的第二行开始,每行对应输出一个雇员的类型、姓名和年薪。
Sample Input
6
Sales Zhangsan 2500 1500
Manager Zhaosi 2500 10000
Manager Liuwu 10000 35000
Sales Sunliu 5000 10000
SalesManager Zhengqi 2500 1500 10000
SalesManager Wangba 10000 25000 10000
Sample Output
Sales Zhangsan : 48000
Manager Zhaosi : 40000
Manager Liuwu : 155000
Sales Sunliu : 180000
SalesManager Zhengqi : 58000
SalesManager Wangba : 430000
题目给定代码
int main()
{
string label, name;
Employee* p[100];
int n;
int base, royalty, bonus;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> label >> name;
if(label == "Sales")
{
cin >> base >> royalty;
p[i] = new Sales(name, base, royalty);
}
if(label == "Manager")
{
cin >> base >> bonus;
p[i] = new Manager(name, base, bonus);
}
if(label == "SalesManager")
{
cin >> base >> royalty >> bonus;
p[i] = new SalesManager(name, base, royalty, bonus);
}
}
for(int i = 0; i < n; i++)
p[i]->print();
for(int i = 0; i < n; i++)
delete p[i];
}
标程
#include <bits/stdc++.h>
using namespace std;
//多态,&引用,*指针,virtual虚函数
class Employee
{
protected :
string name;
int base;
public :
Employee(string n,int b):name(n),base(b){}
virtual void print() = 0;
};
class Manager :public Employee
{
private :
int bonus ;
public :
Manager(string n,int b,int k):Employee(n,b),bonus(k){}
void print()
{
bonus = base*12+bonus;
cout<<"Manager "<<name<<" : "<<bonus<<endl;
}
};
class Sales :public Employee
{
private :
int royalty;
public :
Sales(string n,int b,int k):Employee(n,b),royalty(k){}
void print()
{
royalty = (royalty+base)*12;
cout<<"Sales "<<name<<" : "<<royalty<<endl;
}
};
class SalesManager :public Employee//多重继承慎用!
{
private :
int bonus,royalty;
public :
SalesManager(string n,int b,int k,int kk):Employee(n,b),royalty(k),bonus(kk){}
void print()
{
int sum = 12*(base+royalty)+bonus;
cout<<"SalesManager "<<name<<" : "<<sum<<endl;
}
};
int main()
{
string label, name;
Employee* p[100];
int n;
int base, royalty, bonus;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> label >> name;
if(label == "Sales")
{
cin >> base >> royalty;
p[i] = new Sales(name, base, royalty);
}
if(label == "Manager")
{
cin >> base >> bonus;
p[i] = new Manager(name, base, bonus);
}
if(label == "SalesManager")
{
cin >> base >> royalty >> bonus;
p[i] = new SalesManager(name, base, royalty, bonus);
}
}
for(int i = 0; i < n; i++)
p[i]->print();
for(int i = 0; i < n; i++)
delete p[i];
}