zoukankan      html  css  js  c++  java
  • C++ | 简单工厂模式 | 复数计算器

    简单工厂模式最直观的一个应用便是实现一个计算器的程序。
    比如,公司让你给计算器添加一个幂运算的功能,你只需要设计一个幂运算的类,并实现幂运算的逻辑,然后让该类继承自运算类即可。

    简单工厂模式
    简单工厂模式的设计特点可以防止设计人员私自更改程序中其他函数方法或其他类成员变量。你只能增加新的类方法,无法对已存在的类进行修改。
    比如:老板,让你给公司员工管理程序增加一个考勤计数功能,而你在拿到公司程序源码后偷偷给自己的工资加上一笔,或是在其他功能上做改动,都会造成很严重的后果。而简单工厂模式就可以避免此类事件的发生。
    同时,简单工厂模式也存在一个缺点,在增加新的方法类的时候不是可以任意增加的,必须是工厂类中已存在的可以调动的方法,否则,写好的类是没有办法调用的。由于它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。

    回归正题,说到计算器,下面就来实现一个复数计算器,同理如果是普通计算器只需要删掉下面的复数类,把运算类的成员变量换成相应的类型(int、double)即可。

    
    #include <iostream>
    
    using namespace std;
    
    class Complex
    {
    public:
    	Complex(int real = 0, int imag = 0) :m_real(real), m_imag(imag)
    	{
    	}
    	//"+"重载 
    	Complex operator+(const Complex& c)
    	{
    		//实部+实部//虚部+虚部 
    		return Complex(m_real + c.m_real, m_imag + c.m_imag);
    	}
    	//"-"重载 
    	Complex operator-(const Complex& c)
    	{
    		//实部-实部//虚部-虚部 
    		return Complex(m_real - c.m_real, m_imag - c.m_imag);
    	}
    	//"*"重载 
    	Complex operator*(const Complex& c)
    	{
    		return Complex(m_real * c.m_real - m_imag * c.m_imag, m_imag * c.m_real + m_real * c.m_imag);
    
    	}
    	//"/"重载 
    	Complex operator/(const Complex& c)
    	{
    		/*                  (a+bi)*(c-di)
    		* (a+bi)/(c+di) =   -------------
    		**                     c^2+d^2       
    		*/
    		Complex cTmp;
    		double d;
    		d = c.m_real * c.m_real + c.m_imag * c.m_imag;
    		if (-0.00000001 < d && d < 0.00000001)
    			throw exception("除数不能为0");
    		
    		cTmp.m_real = (m_real * c.m_real - m_imag * (-1) * c.m_imag) / d;
    		cTmp.m_imag = (m_imag * c.m_real + m_real * (-1) * c.m_imag) / d;
    		return cTmp;
    	}
    
    	double m_real;
    	double m_imag;
    };
    
    class Operation						//定义基类:运算类
    {
    public:
    	/*虚函数,实现多态*/
    	virtual Complex GetResult() = 0;
    
    	void SetNumberA(Complex a)
    	{
    		numberA = a;
    	}
    	Complex GetNumberA()
    	{
    		return numberA;
    	}
    
    	void SetNumberB(Complex b)
    	{
    		numberB = b;
    	}
    	Complex GetNumberB()
    	{
    		return numberB;
    	}
    
    protected:
    	Complex numberA;
    	Complex numberB;
    };
    
    class OperationAdd : public Operation		//加法类:继承运算类
    {
    public:
    	virtual Complex GetResult()
    	{
    		Complex tmp;
    		tmp= numberA + numberB;
    		return tmp;
    	}
    };
    
    class OperationSub : public Operation		//减法类:继承运算类
    {
    public:
    	virtual Complex GetResult()
    	{
    		return numberA - numberB;
    	}
    };
    
    class OperationMul : public Operation		//乘法类:继承运算类
    {
    public:
    	virtual Complex GetResult()
    	{
    		return numberA * numberB;
    	}
    };
    
    class OperationDiv : public Operation		//除法类:继承运算类
    {
    public:
    	virtual Complex GetResult()
    	{
    		return numberA / numberB;
    	}
    };
    
    class OperationFactory						//工厂模式:实现对应运算符的实例化
    {
    public:
    	OperationFactory()
    	{
    		operation = NULL;
    	}
    
    	Operation* CreateOperate(char o)
    	{
    		switch (o)
    		{
    		case '+':
    			operation = new OperationAdd();
    			break;
    		case '-':
    			operation = new OperationSub();
    			break;
    		case '*':
    			operation = new OperationMul();
    			break;
    		case '/':
    			operation = new OperationDiv();
    			break;
    		default:
    			throw exception("操作符错误");
    		}
    
    		return operation;
    	}
    
    	~OperationFactory()
    	{
    		delete operation;
    	}
    
    private:
    	Operation* operation;
    };
    
    int main()
    {
    	Complex numberA;
    	Complex numberB;
    	char operate;
    
    	cout << "输入复数A的实部: ";
    	cin >> numberA.m_real;
    	cout << "           虚部: ";
    	cin >> numberA.m_imag;
    
    	cout << "运算符(+ - * /): ";
    	cin >> operate;
    
    	cout << "输入复数B的实部: ";
    	cin >> numberB.m_real;
    	cout << "           虚部: ";
    	cin >> numberB.m_imag;
    
    	OperationFactory factory;		//实例化运算符后返回基类指针
    	Operation* operation;			//接收实例化后的运算符
    
    	try
    	{
    		//实例化运算符
    		operation = factory.CreateOperate(operate);
    	}
    	catch (exception & e)
    	{
    		cout << e.what() << endl;
    		exit(1);
    	}
    	operation->SetNumberA(numberA);
    	operation->SetNumberB(numberB);
    
    	Complex result;
    	try
    	{
    		result = operation->GetResult();
    	}
    	catch (exception & e)
    	{
    		cout << e.what() << endl;
    		exit(1);
    	}
    	cout << "计算结果: (" << result.m_real << ", " << result.m_imag << "i)" << endl;
    
    
    	return 0;
    }
    
    
    

    运行截图:
    加法:
    在这里插入图片描述
    减法:
    在这里插入图片描述
    乘法:
    在这里插入图片描述
    除法:
    在这里插入图片描述

  • 相关阅读:
    《java入门第一季》之面向对象(继承总结)
    《java入门第一季》之面向对象面试题
    《java入门第一季》之面向对象(this和super详细分析)
    《java入门第一季》之面向对象(方法重写问题)
    《java入门第一季》之面向对象面试题(继承中构造方法的关系)
    《java入门第一季》之面向对象面试题(this和super的区别)
    《java入门第一季》之面向对象(继承)
    《java入门第一季》之面向对象(继承)
    Express服务器开发
    WebView 缓存原理分析和应用
  • 原文地址:https://www.cnblogs.com/TaoR320/p/12680143.html
Copyright © 2011-2022 走看看