【实验名称】类和对象
【实验目的】
1、掌握声明类的方法,类和类的成员概念
2、掌握定义对象的方法,理解类和对象的区别;
3、掌握成员函数的实现与调用方法;
【实验原理】
类是由我们根据客观事物抽象而成,形成一类事物,然后用类去定义对象,形成这类事物的具体个体。
类是一个数据类型,类是抽象的,而对象是一个具体的变量,是占用内存空间的。
在C++中可以对类的属性和方法定义访问级别,public修饰的属性和方法,可以在类的内部访问,也可以在类的外部进行访问。private修饰的属性和方法,只能在类的内部进行访问。
【实验内容】
一、设计一个用于描述三维空间中的点的类,为其设计必要的成员变量和函数,并尽量增强其功能。
在这一题中,我构造了一个点类
成员变量包括:
//三维坐标值
double x;
double y;
double z;
成员函数包括:
point(double a, double b, double c);
void central_symmetry();//中心对称
void axial_symmetry();//轴对称
void plane_symmetry();//平面对称
double to_point(double a, double b, double c);//点到点距离
double to_line(point *point1, point *point2);//点到直线距离
double to_plane(point *point1, double A, double B, double C);//点到平面距离
整体程序实现了如下功能:
1.关于原点中心对称的点的坐标
2.关于三个坐标轴对称的点的坐标
3.关于三个坐标轴平面对称的点的坐标
4.计算点到点距离
5.计算点到直线距离
6.计算点到平面距离
7.退出程序
代码:
#include<iostream>
#include <string>
using namespace std;
class point
{
public:
point(double a, double b, double c);
void central_symmetry();//中心对称
void axial_symmetry();//轴对称
void plane_symmetry();//平面对称
double to_point(double a, double b, double c);//点到点距离
double to_line(point *point1, point *point2);//点到直线距离
double to_plane(point *point1, double A, double B, double C);//点到平面距离
private:
//三维坐标值
double x;
double y;
double z;
};
point::point(double a, double b, double c)
{
x = a;
y = b;
z = c;
}
//中心对称
void point::central_symmetry()
{
cout << "点(" << x << "," << y << "," << z << ")关于原点中心对称的点的坐标:\n" << "点(" << -x << "," << -y << "," << -z << ")" << endl;
}
//轴对称
void point::axial_symmetry()
{
cout << "点(" << x << "," << y << "," << z << ")三个坐标轴对称的点的坐标:" << endl;
cout << "x轴 |点(" << x << "," << -y << "," << -z << ")" << endl;
cout << "y轴 |点(" << -x << "," << y << "," << -z << ")" << endl;
cout << "z轴 |点(" << -x << "," << -y << "," << z << ")" << endl;
}
//平面对称
void point::plane_symmetry()
{
cout << "点(" << x << "," << y << "," << z << ")关于三个坐标轴平面对称的点的坐标:" << endl;
cout << "x_y平面 |点(" << x << "," << y << "," << -z << ")" << endl;
cout << "x_z平面 |点(" << x << "," << -y << "," << z << ")" << endl;
cout << "y_z平面 |点(" << -x << "," << y << "," << z << ")" << endl;
}
//点到点距离
double point::to_point(double a, double b, double c)
{
double distance;
//cout << x << y << z << endl;
//cout << a << b << c << endl;
distance = sqrt((x - a)*(x - a) + (y - b)*(y - b) + (z - c)*(z - c));
//cout << distance << endl;
return distance;
}
//点到直线距离
double point::to_line(point *point1, point *point2)
{
double distance;
double l1 = sqrt((point1->x - point2->x)*(point1->x - point2->x) + (point1->y - point2->y)*
(point1->y - point2->y) + (point1->z - point2->z)*(point1->z - point2->z));
double l2 = sqrt((point1->x - x)*(point1->x - x) + (point1->y - y)*
(point1->y - y) + (point1->z - z)*(point1->z - z));
double l3 = sqrt((x - point2->x)*(x - point2->x) + (y - point2->y)*
(y - point2->y) + (z - point2->z)*(z - point2->z));
double cos = (l1*l1 + l2 * l2 - l3 * l3) / (2 * l1*l2);
distance = l2 * sqrt(1 - cos * cos);
return distance;
}
//点到平面距离
double point::to_plane(point *point1, double A, double B, double C)
{
double distance;
double D;
D = -A * point1->x - B * point1->y - C * point1->z;
distance = abs(A*x + B * y + C * z + D) / sqrt(A*A + B * B + C * C);
return distance;
}
int main()
{
cout << "****************************************" << endl;
cout << "*** 欢迎来到点类 ***" << endl;
cout << "***1.关于原点中心对称的点的坐标 ***" << endl;
cout << "***2.关于三个坐标轴对称的点的坐标 ***" << endl;
cout << "***3.关于三个坐标轴平面对称的点的坐标***" << endl;
cout << "***4.计算点到点距离 ***" << endl;
cout << "***5.计算点到直线距离 ***" << endl;
cout << "***6.计算点到平面距离 ***" << endl;
cout << "***7.退出程序 ***" << endl;
cout << "****************************************\n" << endl;
double x;
double y;
double z;
cout << "请输入你要新创造的点的三维坐标:" << endl;
cin >> x >> y >> z;
point new_point(x, y, z);
cout << "\n*** 新的点诞生了 ***" << endl;
int flag;
while (true)
{
cout << "\n请选择功能:";
cin >> flag;
if (flag == 1)
{
//中心对称
new_point.central_symmetry();
}
else if (flag == 2)
{
//轴对称
new_point.axial_symmetry();
}
else if (flag == 3)
{
//平面对称
new_point.plane_symmetry();
}
else if (flag == 4)
{
//点到点距离
cout << "请输入另一个点的三维坐标:" << endl;
cin >> x >> y >> z;
double distance = new_point.to_point(x, y, z);
cout << "两点之间的距离为:" << distance << endl;
}
else if (flag == 5)
{
//点到直线距离
cout << "请输入直线上的两个点:" << endl;
cin >> x >> y >> z;
point *point1 = new point(x, y, z);
cin >> x >> y >> z;
point *point2 = new point(x, y, z);
double distance = new_point.to_line(point1, point2);
cout << "点到直线的距离为:" << distance << endl;
}
else if (flag == 6)
{
//点到平面距离
double A, B, C;
cout << "请输入平面上的一个点:" << endl;
cin >> x >> y >> z;
point *point1 = new point(x, y, z);
cout << "请输入平面的任一法向量参数:" << endl;
cin >> A >> B >> C;
double distance = new_point.to_plane(point1, A, B, C);
cout << "点到平面的距离为:" << distance << endl;
}
else if (flag == 7)
{
//退出
cout << "成功退出!" << endl;
break;
}
}
return 0;
}
运行演示:
二、设计一个描述动物的类,为其设计必要的成员变量和函数,并尽量增强其功能。
在这一题中,我构造了一个“神奇的小蛇”类以及一个辅助实现游戏功能的“苹果”类,意图实现一个类似于贪吃蛇的功能。
“神奇的小蛇”类成员变量包括:
string name;//名字
int ages;//年龄
string color;//花纹
double weight;//体重
int position_x;//水平位置
int position_y;//竖直位置
int apple_ans;//吃苹果总数
成员函数包括:
//蛇类构造函数
snake(string this_name,int this_ages,string this_color, double this_weight);
//修改小蛇的基本信息
void alter(string this_name, int this_ages, string this_color, double this_weight);
//小蛇移动
void move();
//小蛇究极进化
void jinhua();
//小蛇吃苹果
int eat(int apple_position_x, int apple_position_y);
//显示小蛇的基本信息
void show();
//显示小蛇位置
void show_position();
整体程序实现了如下功能:
1.显示小蛇的基本信息
2.修改小蛇的基本信息
3.小蛇移动(二位平面,上下左右移动)
4.小蛇吃苹果(若该位置有苹果则吃苹果,体重+1,吃苹果总数+1,苹果重新随机生成;若该位置没有苹果则输出这里没有苹果)
5.小蛇究极进化(若小蛇吃过苹果2个以上苹果则顺利进化成五爪金龙,否则进化失败)
6.退出神奇的小蛇
代码:
#include<iostream>
#include <string>
#include<time.h>
using namespace std;
//蛇类
class snake
{
public:
//蛇类构造函数
snake(string this_name,int this_ages,string this_color, double this_weight);
//修改小蛇的基本信息
void alter(string this_name, int this_ages, string this_color, double this_weight);
//小蛇移动
void move();
//小蛇究极进化
void jinhua();
//小蛇吃苹果
int eat(int apple_position_x, int apple_position_y);
//显示小蛇的基本信息
void show();
//显示小蛇位置
void show_position();
private:
string name;//名字
int ages;//年龄
string color;//花纹
double weight;//体重
int position_x;//水平位置
int position_y;//竖直位置
int apple_ans;//吃苹果总数
};
//蛇吃的苹果类
class apple
{
public:
//苹果构造函数
apple();
//显示苹果位置
void show_apple_position();
int position_x;//水平位置
int position_y;//竖直位置
bool exist;//苹果是否还存在
};
//苹果构造函数
apple::apple()
{
srand(unsigned(time(0)));
position_x = rand() % 11;
position_y = rand() % 11;
exist = 1;
}
//显示苹果位置
void apple::show_apple_position()
{
cout << "当前苹果的位置:" << position_x << " " << position_y << endl;
}
//修改小蛇的基本信息
void snake::alter(string this_name, int this_ages, string this_color, double this_weight)
{
name = this_name;
ages = this_ages;
color = this_color;
weight = this_weight;
show();
}
//蛇类构造函数
snake::snake(string this_name, int this_ages, string this_color, double this_weight)
{
name = this_name;
ages = this_ages;
color = this_color;
weight = this_weight;
position_x = 0;
position_y = 0;
apple_ans = 0;
}
//显示小蛇的基本信息
void snake::show()
{
cout << "*********************************" << endl;
cout << "* 神奇小蛇的名字:" << name << " \t*" << endl;
cout << "* 神奇小蛇的年龄:" << ages << " \t*" << endl;
cout << "* 神奇小蛇的花纹:" << color << " \t*" << endl;
cout << "* 神奇小蛇的体重:" << weight << " \t*" << endl;
cout << "* 神奇小蛇的位置:" << position_x << " " << position_y << " \t*" << endl;
cout << "*********************************" << endl;
}
//显示小蛇位置
void snake::show_position()
{
cout << "当前神奇小蛇的位置:" << position_x << " " << position_y << endl;
}
//小蛇移动
void snake::move()
{
int a, b;
cout << "请输入小蛇水平移动步数(正数代表向右):";
cin >> a;
cout << "请输入小蛇垂直移动步数(正数代表向上):";
cin >> b;
position_x = position_x + a;
position_y = position_y + b;
show_position();
}
//小蛇吃苹果
int snake::eat(int apple_position_x, int apple_position_y)
{
if (apple_position_x == position_x && apple_position_y == position_y)
{
apple_ans++;
weight++;
cout << "小蛇吃了一个苹果" << endl;
cout << "小蛇一共吃了" << apple_ans << "个苹果" << endl;
cout << "小蛇体重+1" << endl;
return 1;
}
else
{
cout << "这里没苹果,你吃啥?" << endl;
return -1;
}
}
//小蛇究极进化
void snake::jinhua()
{
if (apple_ans >= 2)
{
cout << "小蛇顺利进化!" << endl;
name = "五爪金龙";
ages = 99;
color = "金色鳞片";
weight = 99;
show();
}
else
{
cout << "小蛇还没吃苹果呢!" << endl;
}
}
int main()
{
//freopen("in.txt", "r", stdin);
cout << "****************************" << endl;
cout << "***欢迎来到贪吃的神奇小蛇***" << endl;
cout << "***1.显示小蛇的基本信息 ***" << endl;
cout << "***2.修改小蛇的基本信息 ***" << endl;
cout << "***3.小蛇移动 ***" << endl;
cout << "***4.小蛇吃苹果 ***" << endl;
cout << "***5.小蛇究极进化 ***" << endl;
cout << "***6.退出神奇的小蛇 ***" << endl;
cout << "****************************\n" << endl;
string name;
int ages;
string color;
double weight;
cout << "请输入神奇小蛇的名字:" << endl;
cin >> name;
cout << "请输入神奇小蛇的年龄:" << endl;
cin >> ages;
cout << "请输入神奇小蛇的花纹:" << endl;
cin >> color;
cout << "请输入神奇小蛇的体重:" << endl;
cin >> weight;
snake new_snake(name, ages, color, weight);
cout << "\n***新的神奇小蛇诞生了***" << endl;
new_snake.show();
apple *new_apple = new apple();
int flag;
while (true)
{
if (new_apple->exist == 0)
{
delete new_apple;
new_apple = new apple();
}
cout << "\n请选择功能:";
cin >> flag;
if (flag == 1)
{
//显示小蛇的基本信息
new_snake.show();
}
else if (flag == 2)
{
//修改小蛇的基本信息
cout << "请输入神奇小蛇的名字:" << endl;
cin >> name;
cout << "请输入神奇小蛇的年龄:" << endl;
cin >> ages;
cout << "请输入神奇小蛇的花纹:" << endl;
cin >> color;
cout << "请输入神奇小蛇的体重:" << endl;
cin >> weight;
new_snake.alter(name, ages, color, weight);
}
else if (flag == 3)
{
//小蛇移动
new_apple->show_apple_position();
new_snake.move();
}
else if (flag == 4)
{
//小蛇吃苹果
int judge = new_snake.eat(new_apple->position_x, new_apple->position_y);
if (judge == 1)
{
//若苹果被吃了
new_apple->exist = 0;
}
}
else if (flag == 5)
{
//小蛇究极进化
new_snake.jinhua();
}
else if (flag == 6)
{
//退出
break;
}
}
return 0;
}
运行演示:
三、设计一个矩形类,为其设计必要的成员变量和函数,并尽量增强其功能。
在这一题中,我构造了一个矩形类以及一个用来辅助的点类。
矩形类成员变量包括:
double length;//矩形长
double width;//矩形宽
point centre;//矩形中心点
point Rpoint1;//矩形左上顶点
point Rpoint2;//矩形右上顶点
point Rpoint3;//矩形右下顶点
point Rpoint4;//矩形左下顶点
int rotate;//已旋转度数
成员函数包括:
//构造函数
rectangle(double l, double w, point *temp);
//显示矩形基本信息
void show();
//计算四个顶点(包含旋转)
void calculate();
//计算周长
double perimeter();
//计算面积
double area();
//矩形平移
void move(double a, double b);
//矩形旋转
void turn(int a);
整体程序实现了如下功能:
1.显示矩形的基本信息
2.计算矩形周长
3.计算矩形面积
4.矩形平移
5.矩形旋转(逆时针)
6.退出程序
代码:
#include<iostream>
#include<string>
#define M_PI 3.14159265358979323846
using namespace std;
//点类
class point
{
public:
void alter(double a, double b);
double x;
double y;
};
void point::alter(double a, double b)
{
x = a;
y = b;
}
//矩形类
class rectangle
{
public:
//构造函数
rectangle(double l, double w, point *temp);
//显示矩形基本信息
void show();
//计算四个顶点(包含旋转)
void calculate();
//计算周长
double perimeter();
//计算面积
double area();
//矩形平移
void move(double a, double b);
//矩形旋转
void turn(int a);
private:
double length;//矩形长
double width;//矩形宽
point centre;//矩形中心点
point Rpoint1;//矩形左上顶点
point Rpoint2;//矩形右上顶点
point Rpoint3;//矩形右下顶点
point Rpoint4;//矩形左下顶点
int rotate;//已旋转度数
};
//构造函数
rectangle::rectangle(double l, double w, point *temp)
{
length = l;
width = w;
centre.alter(temp->x, temp->y);
rotate = 0;
calculate();
}
//计算四个顶点(包含旋转)
void rectangle::calculate()
{
//计算无旋转四顶点坐标
Rpoint1.x = centre.x - length / 2;
Rpoint1.y = centre.y + width / 2;
Rpoint2.x = centre.x + length / 2;
Rpoint2.y = centre.y + width / 2;
Rpoint3.x = centre.x + length / 2;
Rpoint3.y = centre.y - width / 2;
Rpoint4.x = centre.x - length / 2;
Rpoint4.y = centre.y - width / 2;
double Rotate = rotate;
Rotate = Rotate * M_PI / 180;
//计算旋转
double temp1, temp2;
temp1 = centre.x + (Rpoint1.x - centre.x)*cos(Rotate) - (Rpoint1.y - centre.y)*sin(Rotate);
temp2 = centre.y + (Rpoint1.x - centre.x)*sin(Rotate) + (Rpoint1.y - centre.y)*cos(Rotate);
Rpoint1.x = temp1;
Rpoint1.y = temp2;
temp1 = centre.x + (Rpoint2.x - centre.x)*cos(Rotate) - (Rpoint2.y - centre.y)*sin(Rotate);
temp2 = centre.y + (Rpoint2.x - centre.x)*sin(Rotate) + (Rpoint2.y - centre.y)*cos(Rotate);
Rpoint2.x = temp1;
Rpoint2.y = temp2;
temp1 = centre.x + (Rpoint3.x - centre.x)*cos(Rotate) - (Rpoint3.y - centre.y)*sin(Rotate);
temp2 = centre.y + (Rpoint3.x - centre.x)*sin(Rotate) + (Rpoint3.y - centre.y)*cos(Rotate);
Rpoint3.x = temp1;
Rpoint3.y = temp2;
temp1 = centre.x + (Rpoint4.x - centre.x)*cos(Rotate) - (Rpoint4.y - centre.y)*sin(Rotate);
temp2 = centre.y + (Rpoint4.x - centre.x)*sin(Rotate) + (Rpoint4.y - centre.y)*cos(Rotate);
Rpoint4.x = temp1;
Rpoint4.y = temp2;
}
//显示矩形基本信息
void rectangle::show()
{
cout << "************************************" << endl;
cout << " 矩形的基本信息 " << endl;
cout << "1.矩形的长:" << length << endl;
cout << "2.矩形的宽:" << width << endl;
cout << "3.矩形的中心点位置:(" << centre.x << "," << centre.y <<")"<< endl;
cout << "4.矩形的四个顶点位置:"<< endl;
cout << "||点(" << Rpoint1.x << "," << Rpoint1.y << ") ||点(" << Rpoint2.x << "," << Rpoint2.y << ") ||点(" << Rpoint3.x << "," << Rpoint3.y << ") ||点(" << Rpoint4.x << "," << Rpoint4.y << ")" << endl;
cout << "5.矩形已旋转角度:"<< rotate << endl;
cout << "***********************************\n" << endl;
}
//计算周长
double rectangle::perimeter()
{
return 2 * length + 2 * width;
}
//计算面积
double rectangle::area()
{
return length * width;
}
//矩形平移
void rectangle::move(double a, double b)
{
centre.alter(centre.x + a, centre.y + b);
calculate();
show();
}
//矩形旋转
void rectangle::turn(int a)
{
rotate = rotate + a;
calculate();
show();
}
int main()
{
cout << "******************************" << endl;
cout << "*** 欢迎来到矩形类 ***" << endl;
cout << "***1.显示矩形的基本信息 ***" << endl;
cout << "***2.计算矩形周长 ***" << endl;
cout << "***3.计算矩形面积 ***" << endl;
cout << "***4.矩形平移 ***" << endl;
cout << "***5.矩形旋转(逆时针) ***" << endl;
cout << "***6.退出程序 ***" << endl;
cout << "******************************\n" << endl;
double length;
double width;
double x, y;
cout << "请输入你要新创造的矩形的长宽:" << endl;
cin >> length >> width;
cout << "请输入矩形的中心点坐标:" << endl;
cin >> x >> y;
point *point1 = new point;
point1->alter(x, y);
rectangle new_rectangle(length, width, point1);
cout << "\n*** 新的矩形诞生了 ***" << endl;
int flag;
while (true)
{
cout << "\n请选择功能:";
cin >> flag;
if (flag == 1)
{
//显示矩形的基本信息
new_rectangle.show();
}
else if (flag == 2)
{
//计算矩形周长
cout << "矩形的周长为:" << new_rectangle.perimeter() << endl;
}
else if (flag == 3)
{
//计算矩形面积
cout << "矩形的面积为:" << new_rectangle.area() << endl;
}
else if (flag == 4)
{
//矩形平移
double a, b;
cout << "请输入矩形水平移动量(正数代表向右):";
cin >> a;
cout << "请输入矩形垂直移动量(正数代表向上):";
cin >> b;
new_rectangle.move(a, b);
}
else if (flag == 5)
{
//矩形旋转
int a;
cout << "请输入矩形旋转的度数:";
cin >> a;
new_rectangle.turn(a);
}
else if (flag == 6)
{
//退出
cout << "成功退出!" << endl;
break;
}
}
return 0;
}
运行演示:
【小结或讨论】
这一次的三个题目都比较类似,更加准确地说的话,第一题点、第三题矩形更相像,成员变量想来想去也就那几种,更多的是在坐标系中的操作,计算距离、平移、旋转、对称,能想到的都写上了。
第二题我觉得可发挥的空间也是最大的。意外地想到想做一个贪吃蛇的游戏作为载体,当然为了减少工作量,并没有写一个可视化的图像出来,只是把贪吃蛇的大概意思实现了一下。实现的过程也遇到了非常多的问题。比如那个苹果的生成,一开始写错了,每次循环就重新生成了一次,结果怎么也吃不到苹果;之后又因为被吃掉后的重新随机生成,困扰好久。一会苹果一直不重新生成,一会指向苹果的指针又飞了。该如何销毁原来的苹果,重新构造新的苹果,delete new_apple以及new_apple = new apple()该放哪,也是让我分析了好一会,好在最后还是顺利解决了。