2017《面向对象程序设计》课程作业七

题目描述

  • 请将随机生成数字、表达式的部分设计成:一个Random基类,基类中有random()方法。并由该基类派生出RandomNumber类、RandomOperation类,继承并覆盖父类方法。
  • 学习简单工厂模式,思考能否将该模式运用到题目的第一点要求中。

作业要求

  • 体会继承和多态的思想
  • 发表一篇博客,博客内容为:提供本次作业的github链接,题目描述的代码部分的解释、简单工厂模式的学习。

简单工厂模式的学习

  • 为什么要使用简单工厂模式:保证代码的可复用,各个子类完全分离,避免了更高代码无意中把原来好的源代码改错,个人只用负责自己对应的子类,不用别的子类。
  • 使用简单工程模式的大致流程:告诉工厂你所需要的对象->工厂new出一个对象->工厂返回一个指向该对象的指针。
  • 创建简单工厂模式的大致流程:创建定义一个基类(其中包括虚函数)->创建定义多个子类(包括虚函数的新定义)->建立工厂类(建立静态函数,根据不同的输入返回不同对象的指针)。
  • 静态的函数中static的含义和好处:“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
  • 虚函数:简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性,多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。在本次作业中,虚函数的作用是:使用指向不同子类的指针调用虚函数,虚函数的名字和用法都相同,但是作用却不同,这也体现了多态性。
  • 简单工厂模式的例子及其代码实现

github链接

主要代码:

//******.h文件中的类实现*******
class Random//基类
{
public:void init();//初始化随机数生成器
	virtual int random();
};
class RandomNumber :public Random
{
public:RandomNumber(){}
	virtual int random();
};
class RandomOperation :public Random
{
public:RandomOperation(){}
	virtual int random();
};
//*******RandomSimpleFactory******
class RandomSimpleFactory//随机类简单工厂
{
public:RandomSimpleFactory(){}
	   static Random* creatRandom(const string &name);
};
//*******.cpp文件中的函数实现********
//*********Random*************
void Random::init()
{
	srand(time(NULL));
}
int Random::random(void)//产生任意的随机数
{
	int a = rand();
	return a;
}
int RandomNumber::random(void)//获取0~10随机的数字
{
	return rand() % 11;
}

int RandomOperation::random(void)//获取随机运算符
{
	int sign;
	int int_sign;
	int_sign = rand() % 4 + 1;
	switch (int_sign)
	{
	case 1:sign = '+'; break;
	case 2:sign = '-'; break;
	case 3:sign = '*'; break;
	case 4:sign = '/'; break;
	}
	return sign;
}
//*********RandomSimpleFactory*****
Random* RandomSimpleFactory::creatRandom(const string &name)
{
	if (name == "Operation")
		return new RandomOperation;
	else if (name == "Number")
		return new RandomNumber;
}
//*********Expression*********
void Expression::randomNumber(void)//获取随机的数字
{
	Random* ran = NULL;
	string name = "Number";
		ran = RandomSimpleFactory::creatRandom(name);
	ran->init();
	a = ran->random();
	b = ran->random();
	c = ran->random();
    d = ran->random();
}
	
void Expression::getsign(void)
{
	Random* ran=RandomSimpleFactory::creatRandom("Operation");
	sign1 = ran->random();
	sign2 = ran->random();
	sign3 = ran->random();
}

遇到问题

主要问题

  • 虚函数的返回类型不同,产生随机数字的子类返回int值,产生随机运算符的子类返回char值,无法成功定义虚函数。
  • 尝试的解决办法:
  1. 使用类模板:在声明和定义类的时候都很自然,但是在简单工厂模式返回一个指针时,就需要定义两个类型指针变量(char和int)来接受返回的指针,在使用时就违背了简单工厂模式的理念,让接口变得复杂。
  2. 使用函数重载:函数重载只能以参数的类型、个数来区分调用的函数,不能用返回值来调用。
  3. 使用不同的虚函数名:这样可以实现,但是不如不使用虚函数,虚函数是在函数名和用法相同的情况下,产生不同的作用的函数,要是使用了不同的虚函数名,就无法体现出多态性。
  4. 最简单的方法:把返回运算符的函数的返回类型设为int,当一个int变量接受char变量值的时候,这个int变量的值就是char所对应的ASC码,将int变量赋值给char 变量时,char变量就会根据这个asc码得到所需的字符。所以只要将虚函数的返回值设为int即可。

其他问题

  • 产生的所有数字都一样,原因:把srand()函数和rand()放在了同一个函数里,每次调用这个函数,就srand()一次,程序运行速度非常快,时间相同,所以种子都是相同的,所以产生的随机数都是相同的。

体会

  • 简单工厂模式的使用,体现了抽象、封装、继承和多态,使类的封装更完善。
  • 虚函数体现了多态和继承,可以函数名相同的问题,简化了函数的使用。
  • 这次作业,要求继承并覆盖父类方法,在这个问题上下了一番功夫,尝试了四种方法,在此过程中收获良多。
  • 继承和多态的体会,贯穿在上文的“简单工厂模式”实现和“遇到问题”中。类的继承,考验人的抽象能力,要将一个对象,抽象成一个类,再提取出他们的共性,就成了父类,一个抽象的类逐渐具体的过程,就是继承的过程。多态简化了代码,方便了分工。相同的代码无需重新复制粘贴,同名的函数也能有序地共存,编码时只要完成自己的工作,无需过分考虑重名的问题,无形中也简化了编码时的思维量。
posted @ 2017-06-06 23:45  范加索尔拉  阅读(185)  评论(0编辑  收藏  举报