丹枫虽老犹多态 – 继承与多态

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

-----------------------------------------------------------------------------------------------------------------------------------------------------
代码如下:

#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(){
		int Red_ = 255;
		int Green_ = 255;
		int 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(){
		width_ = 640;
		height_ = 480;
		enter = "enter screen";
	    leave = "leave screen";
		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(){
		this->leftX = 10;
		this->leftY = 10;
		this->rightX = 100;
		this->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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值