问题背景:
编程初学者都会有这样的问题,碰到问题就直觉地用计算机能够理解的逻辑来描述待解决的问题以及具体的求解过程,但这样的程序只为满足当前的需求,不容易维护和拓展。
问题解决思路:
- 设计一段代码之前,首先需要考虑到其可维护、可拓展性;
- 将面向对象特性充分融入到代码设计过程中;
calculator.h
#ifndef _CALCULATOR_H_
#define _CALCULATOR_H_
#include <string>
struct Calculator {
Calculator() = default;
Calculator(double lNum, double rNum)
:leftNumber(lNum), rightNumber(rNum), result(0){}
~Calculator(){}
virtual double getResult() = 0; //基类中可实现也可不实现
protected:
double leftNumber;
double rightNumber;
double result;
};
/*
关于继承方式:
public -- 属性不变
protected -- public变成protected
private -- 都变成private
*/
class CalculatorAdd :public Calculator
{
public:
CalculatorAdd() = default;
CalculatorAdd(double lNum, double rNum)
:Calculator(lNum, rNum){}
~CalculatorAdd(){};
//加
virtual double getResult();
};
class CalculatorSub :public Calculator
{
public:
CalculatorSub() = default;
CalculatorSub(double lNum, double rNum)
:Calculator(lNum, rNum){}
~CalculatorSub(){};
//减
virtual double getResult();
};
class CalculatorMul :public Calculator
{
public:
CalculatorMul() = default;
CalculatorMul(double lNum, double rNum)
:Calculator(lNum, rNum){}
~CalculatorMul(){};
//乘
virtual double getResult();
};
class CalculatorDiv :public Calculator
{
public:
CalculatorDiv() = default;
CalculatorDiv(double lNum, double rNum)
:Calculator(lNum, rNum){}
~CalculatorDiv(){};
//除
virtual double getResult();
};
struct FactoryCalculator {
FactoryCalculator() = default;
FactoryCalculator(std::string op, double num1, double num2);
double getResult(){ return p->getResult(); }//简短函数默认inline
private:
std::string operate;
double number1;
double number2;
Calculator *p;
};
#endif
calculator.cpp
#include "calculator.h"
#include <iostream>
using namespace std; //通常,using只出现在源文件中,而不出现在头文件中
double Calculator::getResult()
{
cout << "message print in Calculator::getResult" << endl;
return 0.0;
}
double CalculatorAdd::getResult()
{
Calculator::getResult();//我曾经来过
result = leftNumber + rightNumber;
return result;
}
double CalculatorSub::getResult()
{
Calculator::getResult();
result = leftNumber - rightNumber;
return result;
}
double CalculatorMul::getResult()
{
Calculator::getResult();
result = leftNumber * rightNumber;
return result;
}
double CalculatorDiv::getResult()
{
Calculator::getResult();
if (rightNumber == 0){
cout << "division cannot be zero" << endl;
return -1;
}
result = leftNumber / rightNumber;
return result;
}
//如果函数体太长,则初始化列表就写在源文件(初始化列表必须跟函数体)
FactoryCalculator::FactoryCalculator(string op, double num1, double num2)
:operate(op), number1(num1), number2(num2)
{
char flag = operate[0];
switch (flag)
{
case '+':
p = new CalculatorAdd(number1, number2);
break;
case '-':
p = new CalculatorSub(number1, num2);
break;
case '*':
p = new CalculatorMul(number1, number2);
break;
case '/':
p = new CalculatorDiv(number1, number2);
break;
default:
break;
}
}
main.cpp
#include "calculator.h"
#include <iostream>
using namespace std;
int main()
{
FactoryCalculator *factoryCalculaotr = new FactoryCalculator("+", 1, 2);
FactoryCalculator *factoryCalculaotr2 = new FactoryCalculator("-", 1, 2);
FactoryCalculator *factoryCalculaotr3 = new FactoryCalculator("*", 1, 2);
FactoryCalculator *factoryCalculaotr4 = new FactoryCalculator("/", 1, 2);
cout << factoryCalculaotr->getResult() << endl;
cout << factoryCalculaotr2->getResult() << endl;
cout << factoryCalculaotr3->getResult() << endl;
cout << factoryCalculaotr4->getResult() << endl;
system("pause");
}