zoukankan      html  css  js  c++  java
  • 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()一次,程序运行速度非常快,时间相同,所以种子都是相同的,所以产生的随机数都是相同的。

    体会

    • 简单工厂模式的使用,体现了抽象、封装、继承和多态,使类的封装更完善。
    • 虚函数体现了多态和继承,可以函数名相同的问题,简化了函数的使用。
    • 这次作业,要求继承并覆盖父类方法,在这个问题上下了一番功夫,尝试了四种方法,在此过程中收获良多。
    • 继承和多态的体会,贯穿在上文的“简单工厂模式”实现和“遇到问题”中。类的继承,考验人的抽象能力,要将一个对象,抽象成一个类,再提取出他们的共性,就成了父类,一个抽象的类逐渐具体的过程,就是继承的过程。多态简化了代码,方便了分工。相同的代码无需重新复制粘贴,同名的函数也能有序地共存,编码时只要完成自己的工作,无需过分考虑重名的问题,无形中也简化了编码时的思维量。
  • 相关阅读:
    MySQL数据库常见面试题
    抽象类与接口
    HashMap与Hashtable的区别
    IDEA破解
    重写equals方法
    MFC编程入门之十七(对话框:文件对话框)
    MFC编程入门之十六(对话框:消息对话框)
    MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
    MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
    MFC编程入门之十二(对话框:非模态对话框的创建及显示)
  • 原文地址:https://www.cnblogs.com/vancasola/p/6954249.html
Copyright © 2011-2022 走看看