1. 程式人生 > >C++ 類的練習螢幕,形狀,圓,矩形類

C++ 類的練習螢幕,形狀,圓,矩形類

1

1.建立MyShape作為基類 2. 修改MyRectangle類從MyShape派生 3. 修改MyCircle類從MyShape派生 4. 增加createShape()函式根據輸入資訊建立物件 4. 在main函式中建立類的例項。(20分)

題目內容:

增加MyShape類:

  1. 將MyRectangle與MyCircle類中表示顏色的資料域成員,以及setColor(int R, int G, int B)函式均挪到MyShape類中;為R、G、B資料域成員新增getter函式

  2. MyShape類的所有構造造函式均應將顏色初始化為白色,也就是RGB三個顏色分量的值均為255

  3. 在MyShape類中新增純虛擬函式 Draw();並且與 MyRectangle與MyShape類中的Draw()形成覆蓋(override)

  4. 新增兩個 string 型別的私有資料成員 enter 和 leave (需要包含 string 標頭檔案),並且在 MyShape 的建構函式初始化列表中分別對這兩個資料成員初始化為字串 "enter mycircle" 和 "leave mycircle" 

修改MyRectangle類(在第5單元作業程式碼基礎上需修改的內容以加粗下劃線文字表示):

  1. 以公有方式繼承 MyShape 類

  2. 移除表示顏色的資料域成員,以及setColor函式

  3. MyRectangle類的建構函式1接受4個整型引數

  4. 按照順序,這4整型引數分別為矩形的左上頂點的x、y座標,以及右下頂點的x、y座標。(此處不做座標有效性檢查)

  5. MyRectangle類的預設建構函式將矩形左上角頂點的座標均設定為(10,10),將右下角定點座標設定為(100,100)

  6. MyRectangle類的所有建構函式均將顏色初始化為白色,也就是RGB三個顏色分量的值均為255

  7. MyRectangle類的所有建構函式均應使用cout輸出字串“myrectangle”並換行

  8. MyRectangle類中應提供setCoordinations()用於設定對角線的左側及右側頂點座標;函式的引數的含義及型別和建構函式1的前4個引數相同。

  9. MyRectangle類的Draw()函式不再檢查座標的有效性,也不輸出關於座標無效的資訊

  10. 在Draw()中用cout輸出: a. 螢幕的寬度和高度,以空格分隔,然後換行; b. 矩形的左上頂點的x、y座標以及矩形的寬度和高度(座標值以及寬高等4個數值間以1個空格分隔)然後換行; c. 矩形的顏色的RGB分量的值,用空格分隔開的三個整數,然後換行

  11. 如有必要,則增加其他資料成員及函式成員

  12. 不要輸出任何未要求輸出的資訊,不然會導致系統扣分。

新增MyCircle類:

  1. 以公有方式繼承 MyShape 類

  2. 移除表示顏色的資料域成員,以及setColor函式

  3. MyCircle類的建構函式1接受3個整型引數

  4. 按照順序,整型引數分別為圓心的x、y座標,以及圓的半徑。(此處不檢查座標及半徑的有效性)

  5. MyCircle類的預設建構函式將圓心的座標設定為(200,200),半徑設定為100

  6. MyCircle類的所有建構函式均將顏色初始化為白色,也就是RGB三個顏色分量的值均為255

  7. 為MyCircle類新增拷貝建構函式

  8. MyCircle類的所有建構函式均應使用cout輸出字串“mycircle”並換行

  9. MyCircle類中應提供setCenter(int x, int y)用於設定圓心座標,提供setRadius(int r)用於設定圓的半徑。

  10. 在Draw()中用cout輸出:

  11. a. 螢幕的寬度和高度,以空格分隔,然後換行; b. 圓心的x、y座標以及半徑(座標值以及半徑等3個數值間以1個空格分隔)然後換行; c. 圓的顏色的RGB分量的值,用空格分隔開的三個整數,然後換行

  12. 如有必要,則增加其他資料成員及函式成員

  13. 不要輸出任何未要求輸出的資訊,不然會導致系統扣分。

新增createShape() 函式(該函式不屬於任何類):

  1. 函式原型: MyShape* createShape(char shapeType);

  2. 根據引數 shapeType 的值,在堆區建立 MyRectangle 物件或者 MyCircle 物件

  3. 如果 shapeType 的值是字元 c ,則建立 MyCircle 物件,並返回指向該物件的指標

  4. 如果 shapeType 的值是字元 r ,則建立 MyRectangle 物件,並返回指向該物件的指標

  5. 如果 shapeType 的值是其它值,則返回空指標

注:這裡的 createShape 函式及其使用方法,就是設計模式裡面的【工廠模式】的雛形。你可以對java程式設計師說:“牛什麼牛?我們一次作業就學一個設計模式!”

main() 函式:

需使用如下main()函式(不得更改)

  1. int main() {
  2.   const int SHAPENUMBER = 5;
  3.   Screen::getInstance();
  4.   Screen::getInstance();
  5.   char shapeType;
  6.   MyShape* shapes[SHAPENUMBER];
  7.   for(int i = 0; i < SHAPENUMBER; i++) {
  8.     cout << "input shape type" << endl;
  9.     cin >> shapeType;
  10.     shapes[i] = createShape(shapeType);
  11.   }
  12.   MyRectangle* myrectangle;
  13.   MyCircle* mycircle;
  14.   for(int i = 0; i < SHAPENUMBER; i++) {
  15.     mycircle = dynamic_cast<MyCircle*>(shapes[i]);
  16.     myrectangle = dynamic_cast<MyRectangle*>(shapes[i]);
  17.     if ( (mycircle != 0) || (myrectangle != 0)) {
  18.       shapes[i]->setColor(shapeType+i, shapeType+2*i, shapeType+3*i);
  19.       if( typeid(*shapes[i]) == typeid(MyRectangle)) {
  20.         myrectangle -> setCoordinations(10+10*i, 10+10*i, 400+10*i, 200+10*i); 
  21.       } else {
  22.         mycircle -> setCenter(200+10*i, 200+10*i);
  23.         mycircle -> setRadius(50+10*i);
  24.       }   
  25.       shapes[i]->Draw();
  26.     } else {
  27.       cout << "invalid shape" << endl;
  28.     }      
  29.   }
  30.   for(int i = 0; i< SHAPENUMBER; i++) {
  31.       delete shapes[i];
  32.   }
  33.   Screen::deleteInstance();
  34.   cin.get();
  35.   return 0;
  36. }

注:由於 main 函式中使用了 typeid ,因此要在程式中包含標頭檔案 typeinfo。即,在程式頭部新增程式碼:

#include <typeinfo>

輸入格式:

空格分隔的整數

輸出格式:

字串或者空格分隔的整數

輸入樣例:

r cx

c

z

輸出樣例:

invalid screen size

enter screen

leave screen

myrectangle

mycircle

640 480

10 300 690 300

255 255 255

主要練習建構函式及其初始化,構造拷貝函式,靜態成員變數以及靜態成員變數的初始化,虛擬函式,公有繼承,this指標等面向物件程式設計思想

#include <iostream>
#include <cstdlib>
#include <string>
#include <typeinfo>
using namespace std;

class MyShape 
{
private:
	string enter, leave;

public:
	int Red_;
	int Green_;
	int Blue_;

	MyShape():Red_(255),Green_(255),
	Blue_(255),enter("enter mycircle"),
	leave("leave mycircle")
	{}

	void setColor(int R, int G, int B)
	{
		Red_ = R;
		Green_ = G;
		Blue_ = B;
	}

	int getRed() 
	{
		return Red_;
	}

	int getGreen() 
	{
		return Green_;
	}

	int getBlue() 
	{
		return Blue_;
	}

	virtual void Draw() = 0;
};

class Screen 
{
private:
	static Screen* instance;

	Screen():enter("enter screen"),
		leave("leave screen")
	{
		width_ = 640;
		height_ = 480;
		cout << enter << endl;
	}

	Screen(Screen& C) 
	{
		cout << enter << endl;
	}
public:
	static int width_;
	static int height_;
	string enter, leave;

	static Screen* getInstance(int width = 640, int height = 480) {
		if (instance == 0) 
		{
			instance->width_ = width;
			instance->height_ = height;
			if (width>1000 || height>1000 || width <= 0 || height <= 0)
			{
				cout << "invalid screen size" << endl;
				exit(0);
			}
			instance = new Screen;
		}
		else 
		{
			return instance;
		}
	}

	static void deleteInstance() 
	{
		delete instance;
	}

	~Screen() 
	{
		cout << leave << endl;
	}
};

class MyRectangle :public MyShape 
{
public:
	int leftX;
	int leftY;
	int rightX;
	int rightY;
	Screen* p;

	MyRectangle(int leftX, int leftY, int rightX, int rightY)
	{
		this->leftX = leftX;
		this->leftY = leftY;
		this->rightX = rightX;
		this->rightY = rightY;
		Red_ = 255;
		Green_ = 255;
		Blue_ = 255;
		cout << "myrectangle" << endl;
	}

	MyRectangle():leftX(10),leftY(10),
		rightX(100),rightY(100)
	{

		Red_ = 255;
		Green_ = 255;
		Blue_ = 255;
		cout << "myrectangle" << endl;
	}

	void setCoordinations(int leftX, int leftY, int rightX, int rightY) 
	{
		this->leftX = leftX;
		this->leftY = leftY;
		this->rightX = rightX;
		this->rightY = rightY;
	}

	void setScreen(Screen& screen) 
	{
		p = &screen;
		p->width_ = screen.width_;
		p->height_ = screen.height_;
	}

	void Draw()
	{
		cout << Screen::width_ << " " << Screen::height_ << endl;
		cout << leftX << " " << leftY << " " << (rightX - leftX) << " " << (rightY - leftY) << endl;
		cout << Red_ << " " << Green_ << " " << Blue_ << endl;
	}

};

class MyCircle :public MyShape 
{
public:
	int X;
	int Y;
	int R;

	MyCircle():X(200),Y(200),R(100)
	{
		
		Red_ = 255;
		Green_ = 255;
		Blue_ = 255;
		cout << "mycircle" << endl;
	}

	MyCircle(int x, int y, int r):
		X(x),Y(y),R(r)
	{
	
		Red_ = 255;
		Green_ = 255;
		Blue_ = 255;
		cout << "mycircle" << endl;
	}

	// 構造拷貝函式
	MyCircle(MyCircle& C):X(C.X),
		Y(C.Y),R(C.R)
	{
		Red_ = C.Red_;
		Green_ = C.Green_;
		Blue_ = C.Blue_;
	}

	void setCenter(int x, int y)
	{
		X = x;
		Y = y;
	}

	void setRadius(int r) 
	{
		R = r;
	}

	void Draw() 
	{
		cout << Screen::width_ << " " << Screen::height_ << endl;
		cout << X << " " << Y << " " << R << endl;
		cout << Red_ << " " << Green_ << " " << Blue_ << endl;
	}
};

MyShape* createShape(char shapeType) 
{
	MyShape* myshape;
	if (shapeType == 'c') 
	{
		myshape = new MyCircle();
	}
	else if (shapeType == 'r')
	{
		myshape = new MyRectangle();
	}
	else 
	{
		myshape = NULL;
	}
	return myshape;
}

// 靜態成員初始化
int Screen::width_ = 640;
int Screen::height_ = 480;
Screen* Screen::instance = 0;

int main()
{
	const int SHAPENUMBER = 5;
	Screen::getInstance();
	Screen::getInstance();

	char shapeType;
	MyShape* shapes[SHAPENUMBER];
	for (int i = 0; i < SHAPENUMBER; i++) 
	{
		cout << "input shape type" << endl;
		cin >> shapeType;
		shapes[i] = createShape(shapeType);
	}

	MyRectangle* myrectangle;
	MyCircle* mycircle;
	for (int i = 0; i < SHAPENUMBER; i++)
	{
		mycircle = dynamic_cast<MyCircle*>(shapes[i]);
		myrectangle = dynamic_cast<MyRectangle*>(shapes[i]);
		if ((mycircle != 0) || (myrectangle != 0)) {
			shapes[i]->setColor(shapeType + i, shapeType + 2 * i, shapeType + 3 * i);
			if (typeid(*shapes[i]) == typeid(MyRectangle)) {
				myrectangle->setCoordinations(10 + 10 * i, 10 + 10 * i, 400 + 10 * i, 200 + 10 * i);
			}
			else {
				mycircle->setCenter(200 + 10 * i, 200 + 10 * i);
				mycircle->setRadius(50 + 10 * i);
			}
			shapes[i]->Draw();
		}
		else {
			cout << "invalid shape" << endl;
		}
	}

	for (int i = 0; i< SHAPENUMBER; i++) {
		delete shapes[i];
	}

	Screen::deleteInstance();

	cin.get();
	return 0;
}