增强Screen类,使之在程序中只能生成一个实例(10分)
题目内容:
基于第四单元作业,修改Screen类。第四单元作业的参考代码在下面。
-
在Screen类中,添加两个 string 类型的数据成员 enter 和 leave,并在构造函数中将他们分别初始化为字符串“enter screen”和“leave screen”(每个字符串中只有一个空格分隔两个单词)
-
在Screen类中,增加一个 Screen* 类型的静态的私有数据成员 instance;请在类外将其初始化为 nullptr;
-
在Screen类中,增加一个静态公有的 getInstance(int width, int height) 函数,该函数返回instance的值。两个参数均带有默认值,分别为 640 和 480
-
在getInstance函数中,判断instance的值
-
若instance值为nullptr
a. 以width和height作为构造函数的参数,使用new运算符创建一个Screen对象
b. 将新的Screen对象的地址保存在instance中;
-
若instance的值不为nullptr(即instance指向一个Screen对象),则返回instance的值
-
在getInstance函数中,不检查宽和高是否合理。合理性检测仍然由Screen类的构造函数负责
-
修改Screen类的构造函数
1) 删除Screen类的默认构造函数,只保留带参构造函数,并修改之使其能初始化数据成员
2) 删除第4单元作业的Screen类的所有构造函数中的【cout << “screen” << endl;】语句
3) Screen类的所有构造函数【均应输出】数据成员enter中的字符串内容并换行(使用std::endl),但是【不再输出其它信息】
4) Screen类的构造函数仍然使用第四单元作业中所要求的exitWhenInvalidScreen函数检查屏幕宽和高的有效性。(可以直接复用第四单元作业的相关代码);该部分代码必须放在输出数据成员enter的代码之后
-
如有必要,则增加或者修改其他数据成员及函数成员
-
不要忘记在类外对Screen类的所有静态成员进行初始化,否则编译器会报告链接出错。
-
补充说明
现在的Screen类使用了一种【设计模式】,叫做“单例模式”,可以保证在这个程序中只会有一个Screen的实例。
程序所用主函数如下(不可做任何修改!)
int main() {
int width, height;
Screen *screen1, *screen2;
std::cin >> width >> height;
screen1 = Screen::getInstance(width, height);
screen2 = Screen::getInstance();
std::cout << screen1->getWidth() << ' ' << screen1->getHeight() << std::endl;
std::cout << screen2->getWidth() << ' ' << screen2->getHeight();
#ifdef DEBUG
std::cin.get();
#endif
return 0;
}
输入格式:
空格分隔的整数,代表屏幕的宽和高
输出格式:
字符串或者空格分隔的整数
输入样例:
800 600
输出样例:
enter screen
800 600
800 600
注:上述输出样例第三行之后没有换行符
备注:第四单元的作业【创建带有参数边界检查的Screen类】的参考代码如下,如果你未完成第四单元相关作业,那么可以在下面代码的基础上,修改添加代码,完成本次作业
#include <iostream>
#include <cstdlib>
using namespace std;
const int SCREENSIZE = 1000;
class Screen {
private:
int width_, height_;
public:
Screen (int width, int height) {
width_ = width;
height_ = height;
exitWhenInvalidScreen(width, height);
cout << "screen" << endl;
}
Screen () : Screen (640, 480) { // C++11 Delegating Construction
}
int getWidth() {
return width_;
}
int setWidth(int width) {
width_ = width;
exitWhenInvalidScreen(width);
return width_;
}
int getHeight() {
return height_;
}
int setHeight(int height) {
height_ = height;
exitWhenInvalidScreen(640, height);
return height_;
}
void exitWhenInvalidScreen(int width = 640, int height = 480) {
if ( width <= 0 || height <= 0 || width > SCREENSIZE || height > SCREENSIZE) {
cout << "invalid screen size";
exit(0);
}
}
};
int main() {
int width, height;
std::cin >> width >> height;
Screen screen1 (width, height);
Screen screen2;
screen2.setWidth(800);
screen2.setHeight(600);
std::cout << screen1.getWidth() << ' ' << screen1.getHeight() << std::endl;
std::cout << screen2.getWidth() << ' ' << screen2.getHeight();
#ifdef DEBUG
std::cin.get();
#endif
return 0;
}
#include <iostream>
#include <string>
class Screen
{
public:
Screen(int Width,int Height)
{
this -> Width = Width;
this -> Height = Height;
std::cout << this -> enter << std::endl;
this -> exitWhenInvalidScreen(this -> Width,this -> Height);
}
int getWidth()
{
return Width;
}
int getHeight()
{
return this->Height;
}
int setWidth(int width)
{
this->Width = width;
this -> exitWhenInvalidScreen(this -> Width,500);
return width;
} //return width
int setHeight(int height)
{
this->Height = height;
this -> exitWhenInvalidScreen(500,this->Height);
return height;
} //return height
static Screen *getInstance(int width = 640, int height = 480)
{
if(instance == nullptr)
instance = new Screen(width, height);
return instance;
}
private:
static Screen * instance;
std::string enter{"enter screen"}, leave{"leave screen"};
int Width{640},Height{480};
void exitWhenInvalidScreen(int w,int h)
{
if(w > 0 && h > 0 && w <= 1000 && h <= 1000)
return;
else
{
std::cout << "invalid screen size";
exit(0);
}
}
};
Screen * Screen::instance = nullptr;
int main() {
int width, height;
Screen *screen1, *screen2;
std::cin >> width >> height;
screen1 = Screen::getInstance(width, height);
screen2 = Screen::getInstance();
std::cout << screen1->getWidth() << ' ' << screen1->getHeight() << std::endl;
std::cout << screen2->getWidth() << ' ' << screen2->getHeight();
#ifdef DEBUG
std::cin.get();
#endif
return 0;
}