简单说明
大话设计模式开篇的计算器代码的心路历程与我差不多。
从没想过写一个加减乘除会如此麻烦,如此大费周章。
最初的版本是在一个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,括号已经实现,我去休息了,明天优化一下代码。