一个计算器的设计却也体现出了面向对象设计的封装、继承与多态三大特性。
让计算数据和过程与显示结果分开体现了封装的特性;为了程序的可扩展性,比如以后要加入开根号的运算而不去重写整个类,可以将每个操作符单独作为一个类,他们都继承共同的父类------抽象类:Operation类,这里体现了继承和多态的特性。
如何让计算器知道该用哪个操作符的类呢,这里用到了“简单工厂模式”,也就是,到底要实例化哪个操作符类,应该考虑用一个单独的类来做这个创造实例的过程,这就是工厂。
#include <iostream>
#include <exception>
using namespace std;
class Operation
{
public:
virtual double GetResult() = 0;
void SetNumberA( double a )
{
numberA = a;
}
double GetNumberA()
{
return numberA;
}
void SetNumberB( double b )
{
numberB = b;
}
double GetNumberB()
{
return numberB;
}
protected:
double numberA;
double numberB;
};
class OperationAdd : public Operation
{
public:
virtual double GetResult()
{
return numberA + numberB;
}
};
class OperationSub : public Operation
{
public:
virtual double GetResult()
{
return numberA - numberB;
}
};
class OperationMul : public Operation
{
public:
virtual double GetResult()
{
return numberA * numberB;
}
};
class OperationDiv : public Operation
{
public:
virtual double GetResult()
{
if( -0.00000001 < numberB && numberB < 0.00000001 )
throw exception("除数不能为0");
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()
{
double numberA;
double numberB;
char operate;
cout<<"输入数字A: ";
cin>>numberA;
cout<<"运算符(+ - * /): ";
cin>>operate;
cout<<"输入数字B: ";
cin>>numberB;
OperationFactory factory;
Operation* operation;
try
{
operation = factory.CreateOperate( operate );
}
catch(exception& e)
{
cout<<e.what()<<endl;
exit(1);
}
operation->SetNumberA( numberA );
operation->SetNumberB( numberB );
int result;
try
{
result = operation->GetResult();
}
catch( exception& e)
{
cout<<e.what()<<endl;
exit(1);
}
cout<<"计算结果:"<<result<<endl;
delete operation;
return 0;
}