C++ 類的練習螢幕,形狀,圓,矩形類
1
1.建立MyShape作為基類 2. 修改MyRectangle類從MyShape派生 3. 修改MyCircle類從MyShape派生 4. 增加createShape()函式根據輸入資訊建立物件 4. 在main函式中建立類的例項。(20分)
題目內容:
增加MyShape類:
-
將MyRectangle與MyCircle類中表示顏色的資料域成員,以及setColor(int R, int G, int B)函式均挪到MyShape類中;為R、G、B資料域成員新增getter函式
-
MyShape類的所有構造造函式均應將顏色初始化為白色,也就是RGB三個顏色分量的值均為255
-
在MyShape類中新增純虛擬函式 Draw();並且與 MyRectangle與MyShape類中的Draw()形成覆蓋(override)
-
新增兩個 string 型別的私有資料成員 enter 和 leave (需要包含 string 標頭檔案),並且在 MyShape 的建構函式初始化列表中分別對這兩個資料成員初始化為字串 "enter mycircle" 和 "leave mycircle"
修改MyRectangle類(在第5單元作業程式碼基礎上需修改的內容以加粗下劃線文字表示):
-
以公有方式繼承 MyShape 類
-
移除表示顏色的資料域成員,以及setColor函式
-
MyRectangle類的建構函式1接受4個整型引數
-
按照順序,這4整型引數分別為矩形的左上頂點的x、y座標,以及右下頂點的x、y座標。(此處不做座標有效性檢查)
-
MyRectangle類的預設建構函式將矩形左上角頂點的座標均設定為(10,10),將右下角定點座標設定為(100,100)
-
MyRectangle類的所有建構函式均將顏色初始化為白色,也就是RGB三個顏色分量的值均為255
-
MyRectangle類的所有建構函式均應使用cout輸出字串“myrectangle”並換行
-
MyRectangle類中應提供setCoordinations()用於設定對角線的左側及右側頂點座標;函式的引數的含義及型別和建構函式1的前4個引數相同。
-
MyRectangle類的Draw()函式不再檢查座標的有效性,也不輸出關於座標無效的資訊;
-
在Draw()中用cout輸出: a. 螢幕的寬度和高度,以空格分隔,然後換行; b. 矩形的左上頂點的x、y座標以及矩形的寬度和高度(座標值以及寬高等4個數值間以1個空格分隔)然後換行; c. 矩形的顏色的RGB分量的值,用空格分隔開的三個整數,然後換行
-
如有必要,則增加其他資料成員及函式成員
-
不要輸出任何未要求輸出的資訊,不然會導致系統扣分。
新增MyCircle類:
-
以公有方式繼承 MyShape 類
-
移除表示顏色的資料域成員,以及setColor函式
-
MyCircle類的建構函式1接受3個整型引數
-
按照順序,整型引數分別為圓心的x、y座標,以及圓的半徑。(此處不檢查座標及半徑的有效性)
-
MyCircle類的預設建構函式將圓心的座標設定為(200,200),半徑設定為100
-
MyCircle類的所有建構函式均將顏色初始化為白色,也就是RGB三個顏色分量的值均為255
-
為MyCircle類新增拷貝建構函式
-
MyCircle類的所有建構函式均應使用cout輸出字串“mycircle”並換行
-
MyCircle類中應提供setCenter(int x, int y)用於設定圓心座標,提供setRadius(int r)用於設定圓的半徑。
-
在Draw()中用cout輸出:
-
a. 螢幕的寬度和高度,以空格分隔,然後換行; b. 圓心的x、y座標以及半徑(座標值以及半徑等3個數值間以1個空格分隔)然後換行; c. 圓的顏色的RGB分量的值,用空格分隔開的三個整數,然後換行
-
如有必要,則增加其他資料成員及函式成員
-
不要輸出任何未要求輸出的資訊,不然會導致系統扣分。
新增createShape() 函式(該函式不屬於任何類):
-
函式原型: MyShape* createShape(char shapeType);
-
根據引數 shapeType 的值,在堆區建立 MyRectangle 物件或者 MyCircle 物件
-
如果 shapeType 的值是字元 c ,則建立 MyCircle 物件,並返回指向該物件的指標
-
如果 shapeType 的值是字元 r ,則建立 MyRectangle 物件,並返回指向該物件的指標
-
如果 shapeType 的值是其它值,則返回空指標
注:這裡的 createShape 函式及其使用方法,就是設計模式裡面的【工廠模式】的雛形。你可以對java程式設計師說:“牛什麼牛?我們一次作業就學一個設計模式!”
main() 函式:
需使用如下main()函式(不得更改)
- 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;
- }
注:由於 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;
}