实验三 类与对象
分类:
IT文章
•
2023-11-04 20:38:35
PART 1
验证性内容:以多文件结构组织的项目文件示例:在画布上可以上下左右移动的小球
结合示例,搜索了解以下函数的用法及所在头文件
system("pause")
让系统暂停,按任意键继续。头文件#include<cstdlib>
system("color ××")
设置屏幕前景色、背景色。system()的参数必须是const char*类型。
string类的成员函数.c_str()
以char*类型传回string类对象中的字符串
选做*:
Canvas类有许多重复代码,思考如何优化
使用Ball类做一个基于按键的小球移动游戏
丰富功能设计和接口设计
#ifndef BALL_H
#define BALL_H
class Ball {
public:
Ball(int x0=0, int y0=0); // 在坐标(x,y)处构造一个小球(小球用字符O表示)
void left(int step=1); // 左移step
void right(int step=1); // 右移step
void up(int step=1); // 上移step
void down(int step=1); // 下移step
private:
int x; // x坐标
int y; // y坐标
};
#endif
ball.h
#ifndef CANVAS_H
#define CANVAS_H
#include <string>
using std::string;
class Canvas {
public:
Canvas(string bg0="0", string fg0="A");
void changeCanvasBg(string bg0);
void changeCanvasFg(string fg0);
void changeCanvasColor(string bg0, string fg0);
private:
string bg; // background color
string fg; // foreground color
};
#endif
canvas.h
#include "ball.h"
#include <iostream>
#include <cstdlib> // 因为使用了system("cls"); 所以需要包含这个头文件
using std::cout;
using std::endl;
const int SIZE_X=50; // 小球x轴移动范围0~SIZE_X
const int SIZE_Y=50; // 小球y轴移动范围0~SIZE_Y
Ball::Ball(int x0, int y0):x(x0), y(y0) {
// 打印y0-1行空行
for(int line=1; line <= y0-1; line++)
cout << endl;
// 打印x0-1个空格
for(int col=1; col <= x0-1; col++)
cout << " ";
// 打印小球
cout << "O" << endl;
}
void Ball::left(int step) {
x = x-step;
if(x <= 0)
x=0;
// 清屏
system("cls");
// 打印y-1行空行
for(int line=1; line <= y-1; line++)
cout << endl;
// 打印x-1个空格
for(int col=1; col <= x-1; col++)
cout << " ";
// 打印小球
cout << "O" << endl;
}
void Ball::right(int step) {
x = x+step;
if(x >= SIZE_X)
x=SIZE_X;
// 清屏
system("cls");
// 打印y-1行空行
for(int line=1; line <= y-1; line++)
cout << endl;
// 打印x-1个空格
for(int col=1; col <= x-1; col++)
cout << " ";
// 打印小球
cout << "O" << endl;
}
void Ball::up(int step) {
y = y-step;
if(y <= 0)
y=0;
// 清屏
system("cls");
// 打印y-1行空行
for(int line=1; line <= y-1; line++)
cout << endl;
// 打印x-1个空格
for(int col=1; col <= x-1; col++)
cout << " ";
// 打印小球
cout << "O" << endl;
}
void Ball::down(int step) {
y = y+step;
if(y >= SIZE_Y)
y = SIZE_Y;
// 清屏
system("cls");
// 打印y-1行空行
for(int line=1; line <= y-1; line++)
cout << endl;
// 打印x-1个空格
for(int col=1; col <= x-1; col++)
cout << " ";
// 打印小球
cout << "O" << endl;
}
ball.cpp
#include "canvas.h"
#include <cstdlib>
Canvas::Canvas(string bg0, string fg0):bg(bg0), fg(fg0) {
string color = "color ";
color += bg0;
color += fg0;
system(color.c_str());
}
void Canvas::changeCanvasBg(string bg0) {
bg = bg0; // 更新画布背景色
string color = "color ";
color += bg;
color += fg;
system(color.c_str());
}
void Canvas::changeCanvasFg(string fg0) {
fg = fg0; // 更新画布前景色
string color = "color ";
color += bg;
color += fg;
system(color.c_str());
}
void Canvas::changeCanvasColor(string bg0, string fg0){
bg = bg0; // 更新画布背景色
fg = fg0; // 更新画布前景色
string color = "color ";
color += bg;
color += fg;
system(color.c_str());
}
canvas.cpp
#include <iostream>
#include "canvas.h"
#include "ball.h"
#include<stdlib.h>
int main() {
Canvas canvas; //创建默认画布,黑底绿色
Ball ball1(10,10);
system("pause");
ball1.left(5);
system("pause");
ball1.up(20);
system("pause");
canvas.changeCanvasFg("E"); // 更新画布前景色
system("pause");
canvas.changeCanvasBg("D"); // 更新画布背景色
system("pause");
system("pause");
return 0;
}
main.cpp
运行效果:

┐( ̄ー ̄)┌没有做什么改动,具体的优化想借着之前用c写的弹跳小球来写个小游戏,然而发现不知不觉时间就消失了,立个flag,这周考完再补充。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i,j;
int x=0;
int y=5;
int velocity_x=1;
int velocity_y=1;
int left=0;
int right=20;
int top=0;
int bottom=10;
while(1)
{
x=x+velocity_x;
y=y+velocity_y;
system("cls");
for(i=0; i<x; i++)
printf("
");
for(j=0; j<y; j++)
printf(" ");
printf("o");
printf("
");
if((x==top)||(x==bottom))
velocity_x=-velocity_x;
if((y==left)||(y==right))
velocity_y=-velocity_y;
}
return 0;
}弹跳
jump ball
预先做的最粗略版效果

PART 2
基于已有信息,补足并扩充程序。 在graph文件夹里提供有三个文件:graph.h、graph.cpp、main.cpp
要求如下:
新建一个空项目,添加上述三个文件到项目中。
补足graph.h中类的成员函数draw()的实现。
选做*:类Graph的扩展功能
支持设置字符尺寸并绘制图形 √
支持设置和调整前景色背景色 --与part1一样
支持通过按键控制图形移动 --待做
#ifndef GRAPH_H
#define GRAPH_H
class Graph {
public:
Graph(char ch=0, int n=1); // 带有参数的构造函数
void draw(); // 绘制图形
void input();
private:
char symbol;
int size;
};
#endif
graph.h
#include"Graph.h"
#include<iostream>
using namespace std;
Graph::Graph(char ch,int n):symbol(ch),size(n){
}
void Graph::draw(){
for(int i=1;i<=size;i++){
for(int j=0;j<size-i;j++){
cout<<" ";
}
for(int k=0;k<2*i-1;k++){
cout<<symbol;
}
cout<<endl;
}
}
void Graph::input()
{
cout<<"输入要打印的字符和行数"<<endl;
cin>>symbol>>size;
}
graph.cpp
#include <iostream>
#include "Graph.h"
#include<stdlib.h>
using namespace std;
int main() {
Graph graph1,graph2;
graph1.input();
graph2.input();
graph1.draw();
system("pause");
graph2.draw();
return 0;
}
main.cpp
运行效果:

PART 3:
设计一个分数类Fraction描述分数
Fraction类对象能够进行以下操作:
加、减、乘、除运算
对两个分数值进行比较运算,返回其大小关系
分数的输入、输出
注意分母为0的边界情况处理
选做*:类Fraction的扩展功能
对分数进行规范化处理,确保分数在形式上,只有分字为负数,并且,分数值是约简形式,即:
2/-3 经过规范化处理后,转换为 -2/3 √
15/21 经过规范化处理后,转换为5/7 √
-2/-6 经过规范化处理后,转换为1/3 √
实现分数到小数的转换。例如,3/4会转换为0.75输出。
#ifndef FRACTION_H
#define FRACTION_H
class fraction
{
public:
fraction(int m=0,int n=1);
void com(fraction &a,fraction &b);
int gys(int x,int y) //求最小公约数
{
return y?gys(y,x%y):x;
}
int gbs(int x,int y) //求最小公倍数
{
return x/gys(x,y)*y;
}
void yuefen(int fz,int fm);
void yuefen(fraction &k); //约分
void add(fraction &a,fraction &b);
void sub(fraction &a,fraction &b);
void mul(fraction &a,fraction &b);
void div(fraction &a,fraction &b);
void transform();
void input();
private:
int bottom;
int top;
};
#endif
fraction.h
#include"Graph.h"
#include<iostream>
using namespace std;
Graph::Graph(char ch,int n):symbol(ch),size(n){
}
void Graph::draw(){
for(int i=1;i<=size;i++){
for(int j=0;j<size-i;j++){
cout<<" ";
}
for(int k=0;k<2*i-1;k++){
cout<<symbol;
}
cout<<endl;
}
}
void Graph::input()
{
cout<<"输入要打印的字符和行数"<<endl;
cin>>symbol>>size;
}
graph.cpp
#include <iostream>
#include "Graph.h"
#include<stdlib.h>
using namespace std;
int main() {
Graph graph1,graph2;
graph1.input();
graph2.input();
graph1.draw();
system("pause");
graph2.draw();
return 0;
}
main.cpp
运行效果:

总结:1.分数计算器写的比较幼稚,实用性不强。不能实现混合运算和优先度运算,也不能实现连续运算,需要以后进行修改。
2.关于分数转换成小数,学习了一些保留位数和转换的用法。
详见:setprecision()用法---https://blog.****.net/mbxc816/article/details/7193615
----X.Raven