zoukankan      html  css  js  c++  java
  • 《面向对象程序设计》课程作业七

    题目描述

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


    普通的继承!

    #include<iostream>
    #include<ctime>
    using namespace std;
    
    class Random {
    private:
    	static unsigned int seed;
    public:
    	void Next();
    	virtual ~Random() {}
    	virtual void random() = 0;
    };
    
    unsigned int Random::seed = (unsigned int)time(NULL);
    
    void Random::Next()/*每次随机后让种子变成一个新的*/
    {
    	seed = seed * 11035 + 12345;
    	seed = (unsigned int)(seed / 65536) % 32768;
    }
    
    class RandomNum : public Random
    {
    private:
    	int num;
    public:
    	RandomNum() { num = 0; }
    	virtual void random();
    	int GetNum() { return num; }
    };
    
    void RandomNum::random()
    {
    	num = rand() % 11;
    	Next();
    }
    
    class RandomOper : public Random
    {
    private:
    	char oper;
    public:
    	RandomOper() { oper = '+'; }
    	virtual void random();
    	char GetOper() { return oper; }
    };
    
    void RandomOper::random()
    {
    	int choice = rand() % 4;
    	switch (choice)
    	{
    	case'0':oper = '+'; break;
    	case'1':oper = '-'; break;
    	case'2':oper = '*'; break;
    	case'3':oper = '/'; break;
    	default:
    		break;
    	}
    	Next();
    }
    
    int main()
    {
    	RandomNum rnd1;
    	rnd1.random();
    	cout << rnd1.GetNum() << endl;
    
    	RandomOper rnd2;
    	rnd2.random();
    	cout << rnd2.GetOper() << endl;
    
    	return 0;
    }
    

    简单工厂:

    工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。

    工厂根据一个字符串来生成数字or运算符。

    class RandomFactory
    {
    public:
        Random createRandom(const string &s);
        RandomFactory();
        ~RandomFactory();
    };
    
    
    Random * Randomfactory::creatrandom(const int & s) 
    {
        if (s == "number")
        {
            return new RandomNum();
        }
        if (s == "operator")
        {
            return new RandomOper();
        }
        else
        {
            assert(false);
        }
        return NULL;
    }
    

    其余的部分逻辑相似,不贴了。

    模板实现

    我想到我学C#时,觉得C#自带的Random类特别方便。先创建一个Random类的对象比如rnd,然后就可以rnd.Next(int n) 生成一个随机数。

    因为还要随机生成运算符,就用了模板。

    一开始我还傻乎乎的以为很好写,就像下面这样:

    这肯定是不行的,经过搜索,实现这样的功能要用到类模板特化的知识点。看看我的类声明:

    template<class T>
    class Random {
    protected:
    	static unsigned int seed;
    public:
    	static void NextSeed();
    	T Next();
    };
    

    如果你传int参数进去,Next方法就生成一个随机数,如果你传的是char,那么生成一个运算符。

    但对于NextSeed方法,我们不希望将其特化,因为无论对于那种类型,NextSeed的行为都希望是一样的。这就涉及到类模板的成员函数的特化。写的时候报错无数,看文档也学到了不少,在代码中也注释了方便以后重看时回忆。

    github上是简单继承和模板特化的两个写法。下图是实现了C#写法的效果:


    学习链接:

    编译器报错文档:

    编译器错误 C2910检测到尝试两次显式专用化函数C2248中不能访问访问成员声明C2352非静态成员函数的非法调用

  • 相关阅读:
    spring boot 2 上传文件大小限制的配置不生效解决方式
    jsr基本使用@valid和@validation
    C#基础拾遗系列之一:先看懂IL代码
    ideal key
    dotnet watch+vs code提升asp.net core开发效率
    Mybatis使用
    java webservice
    JavaScript ES6 规范
    Express (Routing、Middleware、托管静态文件、view engine 等等)
    mongoDB (mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
  • 原文地址:https://www.cnblogs.com/ZCplayground/p/6962002.html
Copyright © 2011-2022 走看看