Menu
Coddy logo textTech

OOP에서의 예외 처리

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 81번째.

예외 처리는 C++에서 런타임 오류를 감지하고 대응하는 구조화된 방법을 제공합니다. 객체 지향 프로그래밍에서 예외는 클래스 계층 구조와 자연스럽게 통합되므로, 무엇이 잘못되었는지에 대한 context를 담은 의미 있는 오류 유형을 생성할 수 있습니다.

기본 메커니즘은 세 가지 키워드인 try, throw, catch를 사용합니다. 실패할 수도 있는 코드는 try 블록에 들어가고, 오류는 throw로 알리며, catch 블록은 특정 예외 유형을 처리합니다.

#include <iostream>
#include <stdexcept>

class BankAccount {
    double balance;
public:
    BankAccount(double b) : balance(b) {}
    
    void withdraw(double amount) {
        if (amount > balance) {
            throw std::runtime_error("Insufficient funds");
        }
        balance -= amount;
    }
    
    double getBalance() const { return balance; }
};

int main() {
    BankAccount account(100.0);
    
    try {
        account.withdraw(150.0);
    } catch (const std::runtime_error& e) {
        std::cout << "Error: "lt;< e.what() << "\n";
    }
    
    std::cout << "Balance: " << account.getBalance() << "\n";
}

C++ 표준 라이브러리는 std::exception을 기반으로 하는 예외 클래스 계층 구조를 제공합니다. 일반적인 파생 클래스에는 런타임 문제를 위한 std::runtime_error와 프로그래밍 실수를 위한 std::logic_error가 포함됩니다. 모든 표준 예외는 오류 메시지를 반환하는 what() 메서드를 제공합니다.

exception이 발생하면 스택이 되감기며, 프로그램이 일치하는 catch block을 찾는 동안 모든 지역 객체에 대해 소멸자가 호출됩니다. 이를 통해 오류가 발생하더라도 적절한 정리가 보장되므로 RAII와 exception 처리가 매우 잘 맞습니다.

challenge icon

챌린지

쉬움

객체 지향 컨텍스트에서 예외 처리를 보여 주는 안전한 나눗셈 계산기를 만들어 보겠습니다. 나눗셈 연산을 수행하고 문제가 발생하면 의미 있는 예외를 발생시키는 Calculator class를 만든 다음, main 프로그램에서 해당 예외를 우아하게 처리합니다.

코드를 세 개의 파일로 구성합니다.

  • Calculator.h: 적절한 오류 처리를 통해 수학 연산을 수행하는 Calculator class를 Define합니다.

    Calculator에는 나눗셈 결과를 반환하는 method divide(double numerator, double denominator)가 있어야 합니다. 그러나 denominator가 0이면 Division by zero라는 message와 함께 std::runtime_error를 발생시켜야 합니다. numerator 또는 denominator 중 either 하나라도 negative이면 Negative values not allowed라는 message와 함께 std::invalid_argument를 발생시켜야 합니다.

    또한 값의 제곱근을 반환하는 method safeSqrt(double value)도 포함합니다. value가 negative이면 Cannot compute square root of negative number라는 message와 함께 std::runtime_error를 발생시킵니다. sqrt function을 사용하려면 <cmath>를 include해야 합니다.

  • Calculator.cpp: header file에 선언된 methods를 Implement합니다. 필요한 headers(<stdexcept><cmath>)를 include하고 연산을 수행하기 전에 조건을 Check해야 합니다.
  • main.cpp: 세 개의 inputs(각각 별도의 줄에 입력)를 읽습니다.
    1. Operation type: either divide 또는 sqrt
    2. 첫 번째 number (double)
    3. 두 번째 number (double): division에만 사용되며 sqrt에서는 무시됩니다.

    Calculator object를 Create하고 try block 내부에서 요청된 연산을 수행합니다. 연산이 성공하면 Result: [value]를 출력합니다. exception이 catch되면 exception의 what() method에서 가져온 message를 사용하여 Error: [message]를 출력합니다.

    try-catch block 이후에는 exception이 발생했는지 여부와 관계없이 Calculation complete를 출력하여, exceptions을 처리한 후에도 프로그램이 계속 실행된다는 것을 보여 줍니다.

예를 들어 inputs가 divide, 10, 2인 경우:

Result: 5
Calculation complete

inputs가 divide, 10, 0인 경우:

Error: Division by zero
Calculation complete

inputs가 divide, -5, 2인 경우:

Error: Negative values not allowed
Calculation complete

inputs가 sqrt, 16, 0인 경우:

Result: 4
Calculation complete

inputs가 sqrt, -9, 0인 경우:

Error: Cannot compute square root of negative number
Calculation complete

프로그램이 exceptions을 catch하고 의미 있는 messages를 표시하여 errors를 우아하게 처리한 다음 실행을 계속하는 방식을 확인하세요. 이 pattern은 error handling을 깔끔하게 유지하고 main logic이 happy path에 집중할 수 있도록 합니다.

직접 해보기

#include <iostream>
#include <string>
#include "Calculator.h"

using namespace std;

int main() {
    // 입력 읽기
    string operation;
    double num1, num2;
    
    cin >> operation;
    cin >> num1;
    cin >> num2;
    
    // Calculator 객체 생성
    Calculator calc;
    
    // TODO: try-catch 블록을 사용하여 연산을 수행하세요
    // - operation이 "divide"이면 calc.divide(num1, num2)를 호출하세요
    // - operation이 "sqrt"이면 calc.safeSqrt(num1)을 호출하세요
    // - 성공 시 "Result: " 다음에 결과를 출력하세요
    // - 예외를 잡아 "Error: " 다음에 예외 메시지를 출력하세요 (what() 사용)
    // - After the try-catch, always print "Calculation complete"
    
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C++ 컴파일러