프로젝트 6. 클래스 복습(계산기 만들기)
<나의 풀이>
class Calculator
{
protected:
double result; //계산결과
public:
char op; //연산자
static int cnt; //총 계산 횟수
void setOp()
{
cout << "연산자를 입력해주세요 : ";
cin >> this->op;
}
virtual void calculate(double num1, double num2)
{
this->result = 0;
}
double getResult()
{
cout << "--------------------------------------------------\n";
cout << "결과 : " << this->result << endl;
cout << "--------------------------------------------------\n";
return this->result;
}
};
int Calculator::cnt = 0;
- 계산기 클래스이다.
- calculate을 가상함수로 가지고 있다. (자식 클래스에서 오버라이딩)
- getResult는 결과를 출력하고 결과값을 리턴한다.
class Add : public Calculator {
public:
void calculate(double num1, double num2)
{
this->result =(num1 + num2);
}
};
class Sub : public Calculator {
public:
void calculate(double num1, double num2)
{
this->result = (num1 - num2);
}
};
class Mul : public Calculator {
public:
void calculate(double num1, double num2)
{
this->result = (num1 * num2);
}
};
class Div : public Calculator{
public:
void calculate(double num1, double num2)
{
this->result = (num1 / num2);
}
};
- 계산기 클래스를 상속받는 각 연산자 클래스이다.
- calculate메서드를 구현한다.
int main()
{
Calculator* cal = new Calculator();
Add* add = new Add();
Sub* sub = new Sub();
Mul* mul = new Mul();
Div* div = new Div();
double num1, num2;
string flag;
cout << "숫자를 입력해주세요 : ";
cin >> num1;
while (1)
{
cout << "연산을 계속 진행하시겠습니까? (Y: 계속, AC: 초기화, EXIT : 종료) ";
cin >> flag;
if (flag == "EXIT"){
cout << Calculator::cnt << "번 계산했습니다" << endl;
delete add;
delete sub;
delete mul;
delete div;
break;
}
- 사용자로부터 첫번째 숫자를 입력받는다.
- Y: 계속, AC: 초기화, EXIT : 종료 중 하나를 입력받는다.
- EXIT인 경우 총 계산 횟수를 출력하고 동적할당한 클래스 객체들의 메모리를 해제한 후 종료한다.
else if (flag == "Y"){ //계속 진행
cal->setOp();
}
else if (flag == "AC"){ //초기화
cout << "숫자를 입력해주세요 : ";
cin >> num1;
cal->setOp();
}
switch (cal->op){
case '+':
cal = add;
break;
case '-':
cal = sub;
break;
case '*':
cal = mul;
break;
case '/':
cal = div;
break;
}
cout << "숫자를 입력해주세요 : ";
cin >> num2;
cal->calculate(num1, num2);
Calculator::cnt++;
num1 = cal->getResult();
}
}
- AC인 경우에는 사용자에게 숫자를 입력받아 num1 값을 초기화해준다.
- 계산기 클래스의 setOp메서드를 실행하여 연산자를 입력받고 op멤버변수에 저장한다.
- op멤버변수에 따라 조건문을 실행하여 계산기 클래스의 포인터변수를 각 연산자 클래스의 포인터로 업캐스팅 한다.
- calculate메서드를 실행하고 총 계산 횟수를 증가시킨다.
- num1에 계산결과를 저장한다.
<정답풀이>
class Operation {
protected:
double num1, num2;
static double result;
public:
Operation(double num1, double num2) {
this->num1 = num1;
this->num2 = num2;
}
virtual void calculate() = 0;
static double getResult() {
return result;
}
};
double Operation::result = 0;
- 계산 결과를 static으로 선언한다.
- calculate 메서드를 순수가상함수로 지정한다.
class Add : public Operation {
public:
Add(double num1, double num2) : Operation(num1, num2) {};
void calculate() {
result = num1 + num2;
}
};
class Minus : public Operation {
public:
Minus(double num1, double num2) : Operation(num1, num2) {};
void calculate() {
result = num1 - num2;
}
};
class Multiply : public Operation {
public:
Multiply(double num1, double num2) : Operation(num1, num2) {};
void calculate() {
result = num1 * num2;
}
};
class Divide : public Operation {
public:
Divide(double num1, double num2) : Operation(num1, num2) {};
void calculate() {
result = num1 / num2;
}
};
- 각 연산자 클래스는 계산기 클래스를 상속받고 calculate메서드를 구현한다.
double input_double() {
double num;
cout << "숫자를 입력해주세요 : ";
cin >> num;
return num;
}
- 사용자로부터 숫자를 입력받고 그 값을 리턴하는 함수
int main()
{
char op;
double number[2] = {};
double num_in;
Operation* operation;
string isContinue = "AC";
while (1) {
if (isContinue == "EXIT") break;
else if (isContinue == "AC") {
number[0] = input_double();
}
else if (isContinue == "Y") {
number[0] = Operation::getResult();
}
cout << "연산자를 입력해주세요 : ";
cin >> op;
number[1] = input_double();
switch (op) {
case '+':
operation = new Add(number[0], number[1]);
break;
case '-':
operation = new Minus(number[0], number[1]);
break;
case '*':
operation = new Multiply(number[0], number[1]);
break;
case '/':
operation = new Divide(number[0], number[1]);
break;
}
operation->calculate();
delete operation;
cout << "------------------------------------------------------\n";
cout << "결과 : " << Operation::getResult() << endl;
cout << "------------------------------------------------------\n";
cout << "연산을 계속 진행하시겠습니까? (Y: 계속, AC: 초기화, EXIT: 종료) ";
cin >> isContinue;
}
return 0;
}
- 미리 모든 연산자 클래스에 대한 객체를 생성해 두지 않고, 반복문 내에서 할당하여 사용하고 해제한다.
- getResult()의 result는 static이므로 delete해도 값이 사라지지 않는다.