第5单元作业【3】- 在线编程(难度:易)
温馨提示:
1.本次作业属于Online Judge题目,提交后由系统即时判分。
2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩。
在本单元作业【2】的代码基础上,
1. 完善MyRectangle类
2. 创建新类MyCircle
3. 在main函数中创建类的实例。
依照学术诚信条款,我保证此作业是本人独立完成的。
题目内容:
本作业的代码基于本单元作业【2】的代码改进,并且将第4单元作业【3】中的MyRectangle类代码添加到本单元作业中,同时修改MyRectangle类:
-
在MyRectangle类中,添加与颜色相关的属性:增加表示三种颜色分量(红色,绿色,蓝色)的三个数据域成员;
-
在MyRectangle类中,增加函数 setColor(int R, int G, int B);该函数接收三个参数,代表颜色中的Red、Green、Blue分量的大小,该函数将颜色保存在类的数据域成员中。函数返回值自行定义
-
MyRectangle类的默认构造函数将矩形左上角顶点的坐标均设置为(10,10),将右下角顶点坐标设置为(100,100)
-
保留MyRectangle类的带参构造函数和拷贝构造函数,并对他们进行必要的修改
-
MyRectangle类的默认构造函数和带参构造函数需要将表示颜色的数据成员初始化为白色,也就是RGB三个颜色分量的值均为255;拷贝构造函数则不必
-
MyRectangle类的所有构造函数的末尾均应使用cout输出字符串“myrectangle”并换行(使用std::endl)
-
删除MyRectangle类中检查坐标有效性的代码,并删除调用这些代码的代码(注意检查Draw()函数中的代码)
-
Draw()函数中,仅仅只包含如下代码:
a. 用cout输出矩形的左上顶点的x、y坐标以及矩形的宽度和高度(坐标值以及宽高等4个数值间以1个空格分隔)然后换行(使用std::endl);
b. 然后用cout输出矩形颜色的Red、Green、Blue分量的整数值(用十进制输出),用单个空格分隔开这三个整数,然后换行(使用std::endl) -
如有必要,则增加其他数据成员及函数成员
-
不要输出任何未要求输出的信息,尤其是不必要的“空格”,不然会导致测试例无法通过。
main() 函数:
需使用如下main()函数(不得更改)
- int main() {
- int width, height;
- int leftX, leftY, rightX, rightY;
- Screen *screen;
- cin >> width >> height;
- cin >> leftX >> leftY >> rightX >> rightY;
- screen = Screen::getInstance(width, height);
- MyRectangle myRectangle(leftX, leftY, rightX, rightY, screen);
- myRectangle.setColor(0, 0, 0xff);
- myRectangle.Draw();
- screen->deleteInstance();
- #ifdef DEBUG
- std::cin.get();
- #endif
- return 0;
- }
输入格式:
空格分隔的整数
输出格式:
字符串或者空格分隔的整数
输入样例:
640 320
100 101 200 301
输出样例:
enter screen
myrectangle
100 101 100 200
0 0 255
leave screen
注:输出样例公有6行,其中最后一行是空行
---------------------------
第4单元作业【3】中的MyRectangle类的参考代码
这部分代码【仅供参考】。若你没有完成/通过第4单元作业【3】,则可以参考该代码
- class MyRectangle {
- private:
- int x1_, y1_, x2_, y2_;
- Screen* screen_;
- int getWidth() {
- return x2_ - x1_;
- }
- int getHeight() {
- return y2_ - y1_;
- }
- bool isValid() {
- bool isPositive, isInScreen, isLeadingDiagonal;
- isPositive = (x1_ > 0) && (y1_ > 0) && (x2_ > 0) && (y2_ > 0);
- isInScreen = (x1_ < screen_->getWidth()) && (x2_ < screen_->getWidth()) &&
- (y1_ < screen_->getHeight()) && (y2_ < screen_->getHeight());
- isLeadingDiagonal = (getWidth() > 0) && (getHeight() > 0);
- return (isPositive && isInScreen && isLeadingDiagonal);
- }
- public:
- MyRectangle (int x1, int y1, int x2, int y2, Screen* screen) {
- x1_ = x1;
- y1_ = y1;
- x2_ = x2;
- y2_ = y2;
- screen_ = screen;
- cout << "myrectangle" << endl;
- }
- MyRectangle () {
- x1_ = y1_ = x2_ = y2_ = 0;
- screen_ = 0;
- cout << "myrectangle" << endl;
- }
- void setCoordinations(int x1, int y1, int x2, int y2) {
- x1_ = x1;
- y1_ = y1;
- x2_ = x2;
- y2_ = y2;
- }
- void setScreen(Screen& screen) {
- screen_ = &screen;
- }
- void Draw () {
- if (!isValid()) {
- cout << "invalid myrectangle" << endl;
- } else {
- cout << x1_ << " " << y1_ << " " <<
- this->getWidth() << " " <<
- this->getHeight() << endl;
- }
- }
- };
#include <iostream>
#include <string>
using namespace std;
class Screen
{
public:
int getWidth();
int getHeight();
public:
static Screen* getInstance(int width, int height);//3.在Screen类中,增加一个静态公有的 getInstance(int width, int height) 函数,该函数返回instance的值。两个参数均带有默认值,分别为 640 和 480
void deleteInstance();//2.在Screen类中,添加一个deleteInstance()函数
~Screen();//1.为Screen类添加析构函数
private:
int width_;//屏幕的宽
int height_;//屏幕的高
std::string enter;//1.在Screen类中,添加两个 string 类型的数据成员 enter 和 leave,并在构造函数中将他们分别初始化为字符串“enter screen”和“leave screen”(每个字符串中只有一个空格分隔两个单词)
std::string leave;//1.在Screen类中,添加两个 string 类型的数据成员 enter 和 leave,并在构造函数中将他们分别初始化为字符串“enter screen”和“leave screen”(每个字符串中只有一个空格分隔两个单词)
static Screen* instance;//2.在Screen类中,增加一个 Screen* 类型的静态的私有数据成员 instance;
private:
void exitWhenInvalidScreen(int width, int height);//检测屏幕的宽与高是否 符合逻辑
Screen(int width, int height);//将Screen类中的所有构造函数都变成 private 成员
};
int Screen::getWidth()
{
return width_;
}
int Screen::getHeight()
{
return height_;
}
Screen* Screen::getInstance(int width = 640, int height = 480)//3.在Screen类中,增加一个静态公有的 getInstance(int width, int height) 函数,该函数返回instance的值。两个参数均带有默认值,分别为 640 和 480
{
//4.在getInstance函数中,判断instance的值
// 1) 若instance值为0(即“instance是一个空指针”)
// a.以width和height作为构造函数的参数,使用new运算符创建一个Screen对象
// b.将新的Screen对象的地址保存在instance中;
// 2) 若instance的值不为0(即instance指向一个Screen对象),则返回instance的值
if (!instance)
{
instance = new Screen(width, height);
}
return instance;
}
void Screen::deleteInstance()//2.在Screen类中,添加一个deleteInstance()函数
{
delete instance;//功能:将getInstance()函数中申请的内存归还给操作系统。
instance = 0;//将数据成员instance设置为空指针
}
Screen::~Screen()//1.为Screen类添加析构函数
{
std::cout << leave << std::endl;//析构函数应首先输出数据成员leave的内容并换行(使用std::endl)
}
void Screen::exitWhenInvalidScreen(int width, int height)//检测屏幕的宽与高是否 符合逻辑
{
if (width <= 0 || height <= 0)//宽度和高度必须大于0像素(不能等于0像素)
{
std::cout << "invalid screen size";//如果宽或者高不满足上述任一条件,则整个程序仅仅输出字符串"invalid screen size",然后退出程序
exit(0);
}
if (width > 1000 || height > 1000)//宽度和高度均不得大于1000像素(可以等于1000像素)
{
std::cout << "invalid screen size";
exit(0);
}
}
Screen::Screen(int width, int height)//将Screen类中的所有构造函数都变成 private 成员
{
//修改Screen类的构造函数
// 1) 删除Screen类的默认构造函数,只保留带参构造函数,并修改之使其能初始化数据成员
// 2) 删除第4单元作业的Screen类的所有构造函数中的【cout << "screen" << endl; 】语句
// 3) Screen类的所有构造函数【均应输出】数据成员enter中的字符串内容并换行(使用std::endl),但是【不再输出其它信息】
// 4) Screen类的构造函数仍然使用第四单元作业中所要求的exitWhenInvalidScreen函数检查屏幕宽和高的有效性。(可以直接复用第四单元作业的相关代码);该部分代码必须放在输出数据成员enter的代码之后
width_ = width;
height_ = height;
enter = "enter screen";//1.在Screen类中,添加两个 string 类型的数据成员 enter 和 leave,并在构造函数中将他们分别初始化为字符串“enter screen”和“leave screen”(每个字符串中只有一个空格分隔两个单词)
leave = "leave screen";//1.在Screen类中,添加两个 string 类型的数据成员 enter 和 leave,并在构造函数中将他们分别初始化为字符串“enter screen”和“leave screen”(每个字符串中只有一个空格分隔两个单词)
std::cout << enter << std::endl;
exitWhenInvalidScreen(width, height);//检测屏幕的宽与高是否 符合逻辑
}
class MyRectangle {
private:
int x1_, y1_, x2_, y2_;
int R_;//1.在MyRectangle类中,添加与颜色相关的属性:增加表示三种颜色分量(红色,绿色,蓝色)的三个数据域成员;
int G_;
int B_;
Screen* screen_;
int getWidth() {
return x2_ - x1_;
}
int getHeight() {
return y2_ - y1_;
}
public:
MyRectangle(int x1, int y1, int x2, int y2, Screen* screen) {
x1_ = x1;
y1_ = y1;
x2_ = x2;
y2_ = y2;
screen_ = screen;
R_ = 255;//5.MyRectangle类的默认构造函数和带参构造函数需要将表示颜色的数据成员初始化为白色,也就是RGB三个颜色分量的值均为255;拷贝构造函数则不必
G_ = 255;
B_ = 255;
cout << "myrectangle" << endl;//6.MyRectangle类的所有构造函数的末尾均应使用cout输出字符串“myrectangle”并换行(使用std::endl)
}
MyRectangle() {
x1_ = y1_ = 10;//3.MyRectangle类的默认构造函数将矩形左上角顶点的坐标均设置为(10,10),将右下角顶点坐标设置为(100,100)
x2_ = y2_ = 100;
screen_ = 0;
R_ = 255;//5.MyRectangle类的默认构造函数和带参构造函数需要将表示颜色的数据成员初始化为白色,也就是RGB三个颜色分量的值均为255;拷贝构造函数则不必
G_ = 255;
B_ = 255;
cout << "myrectangle" << endl;//6.MyRectangle类的所有构造函数的末尾均应使用cout输出字符串“myrectangle”并换行(使用std::endl)
}
void setCoordinations(int x1, int y1, int x2, int y2) {
x1_ = x1;
y1_ = y1;
x2_ = x2;
y2_ = y2;
}
void setScreen(Screen& screen) {
screen_ = &screen;
}
void Draw() {
//8.Draw()函数中,仅仅只包含如下代码:
// a.用cout输出矩形的左上顶点的x、y坐标以及矩形的宽度和高度(坐标值以及宽高等4个数值间以1个空格分隔)然后换行(使用std::endl);
// b.然后用cout输出矩形颜色的Red、Green、Blue分量的整数值(用十进制输出),用单个空格分隔开这三个整数,然后换行(使用std::endl)
cout << x1_ << " " << y1_ << " " <<
this->getWidth() << " " <<
this->getHeight() << endl;
std::cout << R_ << " " << G_ << " " << B_ << std::endl;
}
void setColor(int R, int G, int B)//2.在MyRectangle类中,增加函数 setColor(int R, int G, int B);该函数接收三个参数,代表颜色中的Red、Green、Blue分量的大小,该函数将颜色保存在类的数据域成员中。函数返回值自行定义
{
R_ = R;
G_ = G;
B_ = B;
}
};
Screen* Screen::instance;//8.不要忘记在类外对Screen类的所有静态成员进行初始化,否则编译器会报告链接出错。
int main() {
int width, height;
int leftX, leftY, rightX, rightY;
Screen *screen;
cin >> width >> height;
cin >> leftX >> leftY >> rightX >> rightY;
screen = Screen::getInstance(width, height);
MyRectangle myRectangle(leftX, leftY, rightX, rightY, screen);
myRectangle.setColor(0, 0, 0xff);
myRectangle.Draw();
screen->deleteInstance();
#ifdef DEBUG
std::cin.get();
#endif
return 0;
}