[포스코x코딩온] 스마트 팩토리 과정 3주차 회고 | 프로젝트 6번 해설

Dana·2023년 4월 9일
0

프로젝트 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해도 값이 사라지지 않는다.

0개의 댓글