C/C++ 《大话设计模式》之 计算器的实现

工厂模式

简单说明

大话设计模式开篇的计算器代码的心路历程与我差不多。
从没想过写一个加减乘除会如此麻烦,如此大费周章。
最初的版本是在一个main函数就解决了。
然后想着用多态去实现。
最后用工厂模式去尝试。
现在实现了加减乘除也保障了满足六大原则。
只是在添加新的功能的时候可能要先构思一下,不过肯定不会修改代码而只是添加代码。

后续用QT弄个界面,再尝试着看能不能写个科学计算器,完善一下。

代码实现

#include <iostream>
#include <string>
#include <map>
#include <functional>
using namespace std;

class Cal
{
public:
	virtual int getResult() = 0;
	int num1;
	int num2;
};
class AddCal :public Cal
{
public:
	virtual int getResult()
	{
		return num1 + num2;
	}
};
class SubCal :public Cal
{
public:
	virtual int getResult()
	{
		return num1 - num2;
	}
};
class MulCal :public Cal
{
public:
	virtual int getResult()
	{
		return num1 * num2;
	}
};
class DivCal :public Cal
{
public:
	virtual int getResult()
	{
		return num1 / num2;
	}
};
class AbsFactory
{
public:
	virtual Cal* Operator() = 0;
};
class AddFactory :public AbsFactory
{
public:
	Cal* Operator()
	{
		return new AddCal;
	}
};
class SubFactory :public AbsFactory
{
public:
	Cal* Operator()
	{
		return new SubCal;
	}
};
class MulFactory :public AbsFactory
{
public:
	Cal* Operator()
	{
		return new MulCal;
	}
};
class DivFactory :public AbsFactory
{
public:
	Cal* Operator()
	{
		return new DivCal;
	}
};
//IOC容器隐藏 加减乘除
template <typename T>
class IOC
{
public:
	template <typename x>
	void input(string key)
	{
		if (m.find(key) == m.end())
		{
			function<T* ()> f = []() { return new x; };
			m[key] = f;
		}
	}
	T* getType(string key)
	{
		if (m.find(key) != m.end())
		{
			function<T* ()> f = m[key];
			return f();
		}
	}
private:
	map<string, function<T* ()>> m;
};

int main()
{
	int num1, num2;
	cin >> num1;
	cin >> num2;
	
	string op;
	cin >> op;

	IOC<AbsFactory> c;
	c.input<AddFactory>("+");
	c.input<SubFactory>("-");
	c.input<MulFactory>("*");
	c.input<DivFactory>("/");
	
	AbsFactory* factory = c.getType(op);
	Cal* cal = factory->Operator();
	
	cal->num1 = num1;
	cal->num2 = num2;
	cout << cal->getResult() << endl;
	return 0;
}

测试截图:
在这里插入图片描述

#include <iostream>
#include <string>
#include <stack>
using namespace std;

int myOperator(char c, int a, int b)
{
	switch (c)
	{
	case '+':return a + b; break;
	case '-':return a - b; break;
	case '*':return a * b; break;
	case '/':return a / b; break;
	}
}
template <class T>
void reverseStack(stack<T>& s1)
{
	stack<T> s2, s3;
	for (int i = 0; s1.size() != 0; ++i)
	{
		s2.push(s1.top());
		s1.pop();
	}
	for (int i = 0; s2.size() != 0; ++i)
	{
		s3.push(s2.top());
		s2.pop();
	}
	for (int i = 0; s3.size() != 0; ++i)
	{
		s1.push(s3.top());
		s3.pop();
	}
}
int main()
{
	stack<int> s1;
	stack<char> s2;
	cout << "input methods" << endl;
	string ch;
	getline(cin, ch);
	int len = ch.size();
	for (int i = 0; i < len; i++) //ch中存储的每个字符拿出来单独判断
	{
		if (ch[i] >= 48 && ch[i] <= 57)//数字判断
		{
			s1.push((int)ch[i] - 48);//整数存入
		}
		//加减乘除判断
		else if (ch[i] == '+' || ch[i] == '-' || ch[i] == '*' || ch[i] == '/' || ch[i] == '(' || ch[i] == ')')
		{
			if (s2.empty() == true)//空栈直接存入
			{
				s2.push(ch[i]);
			}
			else // 非空
			{	//加号减号优先级最低,每次进入先比较
				if (ch[i] == '+' || ch[i] == '-')
				{	//比不过 就将连续的乘除或单个乘除法运算完
					if (s2.top() == '*' || s2.top() == '/')
					{
						char c = s2.top(); s2.pop();
						int num1 = s1.top(); s1.pop();
						int num2 = s1.top(); s1.pop();
						int num3 = myOperator(c, num2, num1);
						s1.push(num3);
					}
					s2.push(ch[i]);//运算结束后存入运算符
				}
				else if (ch[i] == ')')//当遇到右括号则先运算左括号前的运算符
				{
					for (int i = 0; s2.top() != '('; i++)//遇到左括号才退出
					{
						char a = s2.top(); s2.pop();
						int num1 = s1.top(); s1.pop();
						int num2 = s1.top(); s1.pop();
						int num3 = myOperator(a, num2, num1);
						s1.push(num3);
					}
					s2.pop();//  左括号出栈
				}
				else//乘除 左括号时 直接入栈
				{
					s2.push(ch[i]);
				}
			}
		}
	}
	reverseStack(s1);
	reverseStack(s2);
	//如果还剩下没有使用过的加号减号 继续执行 //操作数栈size为1则退出
	for (int i = 0; s1.size() != 1; i++)
	{
		char a = s2.top(); s2.pop();
		int num1 = s1.top(); s1.pop();
		int num2 = s1.top(); s1.pop();
		int num3 = myOperator(a, num1, num2);
		s1.push(num3);
	}
	cout << s1.top() << endl; s1.pop();
	return 0;
}

现在是12点41,括号已经实现,我去休息了,明天优化一下代码。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/GameStrategist/article/details/107840307