习题1
1.1 题目:
请编写程序完成如下设计
- 学生类,数据成员包括学号(公有)、姓名(保护)、年龄(私有)、学生数(静态)。学生数用来统计构造出来的学生对象数量
- 课代表类,继承自学生类,数据包括负责课程编号(公有)、课程评分(公有)
- 要求使用构造初始化符表“:”的形式进行构造,每个类又相关数据的输出显示函数
- 在主函数中构造对象并输出显示相关数据
1.2 解题思路:
- 构建学生类,创建各类数据成员
- 创建课代表类继承学生类
- 初始化静态成员变量
- 构造对象进行调试
1.3 代码及注释:
#include<iostream>
using namespace std;
//定义学生类
class Student {
public:
Student(char* n, int i, int a) {
char *p = new char[strlen(n) + 1];
name = p;
strcpy_s(name, strlen(n) + 1, n);
total_num++;
id = i;
age = a;
}
//获取各个成员变量
static int GetTotal() { return total_num; }
char* GetName() { return name; }
int GetAge() { return age; }
int GetId() { return id; }
//显示学生信息
void Display() {
cout << "Name: " << name << endl;
cout << "Id : " << id << endl;
cout << "Age : " << age << endl << endl;
}
int id;
protected:
char *name;
private:
static int total_num;
int age;
};
//初始化静态成员变量
int Student::total_num = 0;
//定义课代表类
class Lesson_rep :public Student {
public:
Lesson_rep(char* n, int i, int a, int l, double s) :Student(n, i, a) {
lesson_num = l;
score = s;
}
int lesson_num;
double score;
//显示课代表信息
void Display() {
cout << "Name: " << GetName() << endl;
cout << "Id : " << GetId() << endl;
cout << "Age : " << GetAge() << endl;
cout << "Lesson Number: " << lesson_num << endl;
cout << "Lesson Score : " << score << endl << endl;
}
};
int main() {
Student stu1("Mike", 112268, 19);
Student stu2("Eve", 113980, 18);
Student stu3("Michael", 127923, 17);
Lesson_rep stu4("Jack", 118888, 20, 666666, 87.62);
cout << "Information about Michael:" << endl;
stu3.Display();
cout << "Information about Jack:" << endl;
stu4.Display();
cout << "Total Number of Students: " << Student::GetTotal() << endl;
}
1.4 程序运行结果分析:
我们创建4个学生,并展示普通学生Michael的信息和课代表Jack的信息,结果如下:
Information about Michael:
Name: Michael
Id : 127923
Age : 17
Information about Jack:
Name: Jack
Id : 118888
Age : 20
Lesson Number: 666666
Lesson Score : 87.62
Total Number of Students: 4
请按任意键继续. . .
验证可得程序执行正确。
习题2
2.1 题目:
- 定义一个点Point类,数据成员是浮点型横纵坐标;
- 定义一个颜色类Color数据成员只有颜色(字符数组#000000~#FFFFFF);
- 一个直线类Line,数据成员是两个Point对象,表示起点和终点(即Point两个对象为Line的内嵌对象);
- 一个三角形类Triangle,继承自Line和Color,数据成员有三角形的高height,三角形理解成以基类Color为颜色,以基类直线为底,以height为高的直角三角形,(即直线和高分别为两条直角边)请实现相关函数,计算三角形的颜色、周长和面积并给出相关输出
2.2 解题思路:
- 定义点类及其数据成员
- 定义颜色类及其数据成员
- 定义直线类,其包含两个点类对象作为数据成员
- 定义三角形类,继承直线类和颜色类并构造相关的数据成员和成员函数
- 在主函数内构建三角形对象,进行调试测验
2.3 代码及注释:
#include<iostream>
#include<cstring>
using namespace std;
//定义Point类
class Point {
public:
Point() { x = y = 0; }
Point(float a, float b) { x = a, y = b; }
//获取参数x和y
float GetX() { return x; }
float GetY() { return y; }
private:
float x;
float y;
};
//定义Color类
class Color {
public:
Color() { strcpy_s(color, 8, "#000000"); }
Color(char *c) { strcpy_s(color, 8, c); }
//获取颜色参数color
char* GetColor() { return color; }
private:
char color[8];
};
//定义Line类
class Line {
public:
Line() :start(0, 0), end(0, 0) {}
Line(float x1, float y1, float x2, float y2) :start(x1, y1), end(x2, y2) {}
Point* GetStart() { return &start; }
Point* GetEnd() { return &end; }
//获取线段长度
float GetLength() { return sqrt(pow(start.GetX() - end.GetX(), 2) + pow(start.GetY() - end.GetY(), 2)); }
private:
Point start, end;
};
//定义Triangle类
class Triangle :public Line, public Color {
public:
Triangle() :Line(), Color() { height = 0; }
Triangle(char* c, float h, float x1, float y1, float x2, float y2) :Line(x1, y1, x2, y2), Color(c) { height = h; }
//获取面积
float GetArea() { return height * GetLength() * 0.5; }
//获取周长
float GetPerimeter() { return height + GetLength() + sqrt(pow(height, 2) + pow(GetLength(), 2)); }
//显示基本信息
void Display() {
cout << " Color : " << GetColor() << endl;
cout << " Area : " << GetArea() << endl;
cout << " Perimeter : " << GetPerimeter() << endl << endl;
}
private:
float height;
};
int main() {
Triangle test("#CCCCCC", 4, 2, 5, 2, 8);
cout << "Basic Information about Triangle test :" << endl;
test.Display();
return 1;
}
2.4 程序运行结果分析:
结果如下:
Basic Information about Triangle a :
Color : #CCCCCC
Area : 6
Perimeter : 12
请按任意键继续. . .
输出结果均符合检验,因此,程序执行正确。
习题3
3.1 题目:
设计日期类和时间类,并以此两类为基类派生日期时间类
要求:
-
日期类包括年、月、日等成员
-
时间类包括时、分、秒等成员
-
日期时间类能够实现日期时间的求差、比较大小的功能
1、使用运算符重载实现该功能,以时间日期类的对象描述日期时间之差
2、假设每个月都是30天,不考虑闰年
3、不考虑公元前
3.2 解题思路:
-
定义日期类及其数据成员
-
定义时间类及其数据成员
-
定义日期时间类继承日期类和时间类
-
对日期时间类进行关系运算符(==,>,>=,<,<=)重载
-
对日期时间类进行双目运算符(-)重载
-
因为时间不能为负数,故定义减法运算为:
任意两数相减,其结果为大数减去小时,结果为二者时间差
-
在主函数内调试程序
3.3 代码及注释:
#include<iostream>
using namespace std;
// 定义日期类
class Date {
public:
friend class DateTime;
Date() {
year = 2000;
month = 1;
day = 1;
}
Date(int year_, int month_, int day_) {
year = year_;
month = month_;
day = day_;
}
private:
int year;
int month;
int day;
};
// 定义时间类
class Time {
public:
friend class DateTime;
Time() {
hour = 0;
minute = 0;
second = 0;
}
Time(int hour_, int minute_, int second_) {
hour = hour_;
minute = minute_;
second = second_;
}
private:
int hour;
int minute;
int second;
};
// 定义日期时间类,继承日期类和时间类
class DateTime :public Date, public Time {
public:
DateTime() :Date(), Time() {}
DateTime(int year_, int month_, int day_, int hour_, int minute_, int second_)
:Date(year_, month_, day_), Time(hour_, minute_, second_) {}
void Check() {
if (month < 0) {
year--;
month += 12;
}
if (day < 0) {
month--;
day += 30;
}
if (hour < 0) {
day--;
hour += 24;
}
if (minute < 0) {
hour--;
minute += 60;
}
if (second < 0) {
minute--;
second += 60;
}
}
//显示日期时间
void Display() {
cout << year << '-' << month << '-' << day << ' ' << hour << ':' << minute << ':' << second << endl;
}
// 关系运算符重载
bool operator ==(const DateTime &dt) {
if (year == dt.year && month == dt.month && day == dt.day
&& hour == dt.hour && minute == dt.minute && second == dt.second)
return true;
else
return false;
}
bool operator >(const DateTime &dt) {
if (year > dt.year)return true;
else if (year < dt.year)return false;
else if (month > dt.month)return true;
else if (month < dt.month)return false;
else if (day > dt.day)return true;
else if (day < dt.day)return false;
else if (hour > dt.hour)return true;
else if (hour < dt.hour)return false;
else if (minute > dt.minute)return true;
else if (minute < dt.minute)return false;
else if (second > dt.second)return true;
else if (second < dt.second)return false;
else return false;
}
bool operator >=(const DateTime &dt) {
if (year > dt.year)return true;
else if (year < dt.year)return false;
else if (month > dt.month)return true;
else if (month < dt.month)return false;
else if (day > dt.day)return true;
else if (day < dt.day)return false;
else if (hour > dt.hour)return true;
else if (hour < dt.hour)return false;
else if (minute > dt.minute)return true;
else if (minute < dt.minute)return false;
else if (second > dt.second)return true;
else if (second < dt.second)return false;
else return true;
}
bool operator <(const DateTime &dt) {
if (year < dt.year)return true;
else if (year > dt.year)return false;
else if (month < dt.month)return true;
else if (month > dt.month)return false;
else if (day < dt.day)return true;
else if (day > dt.day)return false;
else if (hour < dt.hour)return true;
else if (hour > dt.hour)return false;
else if (minute < dt.minute)return true;
else if (minute > dt.minute)return false;
else if (second < dt.second)return true;
else if (second > dt.second)return false;
else return false;
}
bool operator <=(const DateTime &dt) {
if (year < dt.year)return true;
else if (year > dt.year)return false;
else if (month < dt.month)return true;
else if (month > dt.month)return false;
else if (day < dt.day)return true;
else if (day > dt.day)return false;
else if (hour < dt.hour)return true;
else if (hour > dt.hour)return false;
else if (minute < dt.minute)return true;
else if (minute > dt.minute)return false;
else if (second < dt.second)return true;
else if (second > dt.second)return false;
else return true;
}
// 双目运算符重载
// 因为时间不存在负数,故任意两者的差值是为大数减去小数,即绝对值
DateTime operator -(const DateTime &dt) {
const DateTime *front, *rear;
if (*this > dt) {
front = this;
rear = &dt;
}
else {
front = &dt;
rear = this;
}
DateTime c;
c.year = front->year - rear->year;
c.month = front->month - rear->month;
c.day = front->day - rear->day;
c.hour = front->hour - rear->hour;
c.minute = front->minute - rear->minute;
c.second = front->second - rear->second;
c.Check();
return c;
}
};
int main() {
// 定义两个测试的DataTime对象进行测试
DateTime dt1(2000, 7, 4, 16, 45, 50);
DateTime dt2(2000, 8, 4, 22, 15, 40);
cout << "dt1 = ";
dt1.Display();
cout << "dt2 = ";
dt2.Display();
cout << "dt1 == dt2 :";
if (dt1 == dt2)
cout << "true" << endl;
else
cout << "false" << endl;
cout << "dt1 >= dt2 :";
if (dt1 >= dt2)
cout << "true" << endl;
else
cout << "false" << endl;
cout << "dt1 <= dt2 :";
if (dt1 <= dt2)
cout << "true" << endl;
else
cout << "false" << endl;
cout << "dt1 > dt2 :" ;
if (dt1 >dt2)
cout << "true" << endl;
else
cout << "false" << endl;
cout << "dt1 < dt2 :" ;
if (dt1 < dt2)
cout << "true" << endl;
else
cout << "false" << endl;
DateTime dt3;
dt3 = dt2 - dt1;
cout << "dt2 - dt1 :";
dt3.Display();
return 0;
}
3.4 程序运行结果分析:
调试结果如下:
dt1 = 2000-7-4 16:45:50
dt2 = 2000-8-4 22:15:40
dt1 == dt2 :false
dt1 >= dt2 :false
dt1 <= dt2 :true
dt1 > dt2 :false
dt1 < dt2 :true
dt2 - dt1 :0-1-0 5:29:50
请按任意键继续. . .
验证可得程序执行正确。
习题4
4.1 题目:
设计圆类,并以圆类为基类,派生圆柱类、圆锥类和圆球类(分别求出其面积和体积)
要求:
- 自行确定各类具有的数据成员、函数成员,如果需要对象成员,再自行设计相关类;
- 在设计程序过程中,尽量多地涉及类继承与多态性的重要概念,如虚函数、纯虚函数、抽象基类等等。
4.2 解题思路:
- 构建抽象基类Area和Volume并编写纯虚函数GetArea和GetVolume
- 定义圆类继承抽象基类Area,重写虚函数GetArea
- 定义圆柱类继承圆类和抽象基类Volume,重写虚函数GetArea和GetVolume
- 定义圆锥类继承圆类和抽象基类Volume,重写虚函数GetArea和GetVolume
- 定义圆球类继承圆类和抽象基类Volume,重写虚函数GetArea和GetVolume
- 在主函数内进行调试
4.3 代码及注释:
#include<iostream>
using namespace std;
// 定义数学常数pi
#define pi 3.1415926
// 创建抽象基类Area
class Area {
public:
virtual double GetArea() = 0;
};
// 创建抽象基类Volume
class Volume {
public:
virtual double GetVolume() = 0;
};
// 创建基类Circle圆类
class Circle:public Area {
public:
friend class Cylinder;
friend class Cone;
friend class Sphere;
Circle() {}
Circle(double r_) { r = r_; }
virtual double GetArea() { return pi*r*r; }
private:
double r;
};
// 创建圆柱类
class Cylinder :public Circle, public Volume {
public:
Cylinder() :Circle() {}
Cylinder(double r_, double h_) :Circle(r_) { h = h_; }
virtual double GetArea() { return 2 * pi*r*r + 2 * pi*r*h; }
virtual double GetVolume() { return pi*r*r*h; }
private:
double h;
};
// 创建圆锥类
class Cone :public Circle, public Volume {
public:
Cone() :Circle() {}
Cone(double r_, double h_) :Circle(r_) { h = h_; }
virtual double GetArea() { return pi*r*r + 2 * pi*r*sqrt(h*h + r*r) / 2; }
virtual double GetVolume() { return pi*r*r*h / 3; }
private:
double h;
};
// 创建球类
class Sphere :public Circle, public Volume {
public:
Sphere() :Circle() {}
Sphere(double r_) :Circle(r_) {}
virtual double GetArea() { return 4 * pi*r*r; }
virtual double GetVolume() { return 4 * pi*r*r*r / 3; }
};
int main() {
Circle circle(2);
cout << "创建一个圆对象" << endl;
cout << "半径 :2.0" << endl;
cout << "面积 :" << circle.GetArea() << endl << endl;
Cylinder cylinder(2, 3);
cout << "创建一个圆柱对象" << endl;
cout << "半径 :2.0" << endl;
cout << "高度 :3.0" << endl;
cout << "面积 :" << cylinder.GetArea() << endl;
cout << "体积 :" << cylinder.GetVolume() << endl << endl;
Cone cone(2, 3);
cout << "创建一个圆锥对象" << endl;
cout << "半径 :2.0" << endl;
cout << "高度 :3.0" << endl;
cout << "面积 :" << cone.GetArea() << endl;
cout << "体积 :" << cone.GetVolume() << endl << endl;
Sphere sphere(2);
cout << "创建一个球对象" << endl;
cout << "半径 :2.0" << endl;
cout << "面积 :" << sphere.GetArea() << endl;
cout << "体积 :" << sphere.GetVolume() << endl << endl;
return 0;
}
4.4 程序运行结果分析:
创建对象进行测试,结果如下:
创建一个圆对象
半径 :2.0
面积 :12.5664
创建一个圆柱对象
半径 :2.0
高度 :3.0
面积 :62.8319
体积 :37.6991
创建一个圆锥对象
半径 :2.0
高度 :3.0
面积 :35.2207
体积 :12.5664
创建一个球对象
半径 :2.0
面积 :50.2655
体积 :33.5103
请按任意键继续. . .
根据验算得结果均无误,因此,程序执行正确。