C++에서 try-catch 문은 예외가 발생할 수 있는 코드 블록을 감싸고, 발생한 예외를 적절하게 처리하는 메커니즘을 제공한다.
try-catch 기본 구문
try {
// 예외가 발생할 수 있는 코드
} catch (예외_유형1& e) {
// 예외_유형1에 해당하는 예외 처리
} catch (예외_유형2& e) {
// 예외_유형2에 해당하는 예외 처리
} catch (...) {
// 기타 모든 예외를 처리하는 블록
}
- try 블록: 예외가 발생할 수 있는 코드를 포함하는 블록. 이 블록 내에서 예외가 발생하면 예외를 던진다.
- catch 블록: 발생한 예외를 처리하기 위한 블록. catch 블록은 발생한 예외의 유형에 따라 여러 개를 사용할 수 있다. 가장 specific한 예외 유형부터 순서대로 체크하며, 마지막 catch 블록은 모든 예외를 처리하기 위해 사용된다. 이 블록은 예외의 유형을 명시하지 않고, ...으로 표시할 수 있다.
- 예외 유형: 처리할 예외의 유형을 나타내는 C++ 예외 클래스. 예외 유형은 사용자 정의 예외 클래스일 수도 있고, 표준 예외 클래스 중 하나일 수도 있다.
- e: 예외 객체의 이름. 예외 객체에는 발생한 예외에 대한 정보가 포함되어 있으며, catch 블록 내에서 참조할 수 있다.
사용자가 직접 std::runtime_error 예외를 던지고 해당 예외 객체에 문자열 메시지를 전달하는 예제
#include <iostream>
int main() {
try {
int dividend, divisor;
std::cout << "Enter dividend: ";
std::cin >> dividend;
std::cout << "Enter divisor: ";
std::cin >> divisor;
if (divisor == 0) {
// std::runtime_error 예외 던지면서 메시지 전달
throw std::runtime_error("Division by zero is not allowed.");
}
double result = static_cast<double>(dividend) / divisor;
std::cout << "Result: " << result << std::endl;
} catch (const std::exception& e) {
// 예외 객체를 통해 메시지 출력
std::cout << "An exception occurred: " << e.what() << std::endl;
}
return 0;
}
✔ C++ 표준 라이브러리의 std::exception 클래스를 상속받는 여러 예외 클래스
- std::runtime_error : 프로그램 실행 중 발생하는 오류
- std::logic_error : 논리 오류. 예를 들어, 잘못된 인자를 전달한 경우 등
- std::invalid_argument : 잘못된 인수를 전달한 경우 발생하는 예외 클래스
- std::out_of_range : 범위를 벗어난 인덱스나 값에 접근한 경우 발생하는 예외 클래스
- std::bad_alloc : 동적 메모리 할당에 실패한 경우 발생하는 예외 클래스
이 외에도 다양한 예외 클래스가 있다.
사용자 정의 예외 객체를 만들어 예외를 throw할 수도 있고, 명시적으로 throw 문을 사용하지 않아도 일부 상황에서 자동으로 예외를 발생시키고 처리할 수 있는 예외 처리 메커니즘을 제공된다
✔ std::exception은 C++ 표준 예외 클래스의 기본 클래스로 이 매개변수 유형을 사용하면 모든 종류의 예외를 잡을 수 있다. 하지만, catch 블록에서 std::exception을 사용하여 모든 예외를 처리하는 것은 예외 처리의 마지막 수단으로 사용되어야 한다.
왜냐하면 예외의 구체적인 유형을 알 수 없기 때문에, 다운캐스팅(dynamic_cast)의 방법을 쓰지 않는 이상 예외의 세부 정보를 알 수 없고 적절한 조치를 취하는 것이 어렵기 때문이다. 때문에 최대한 예외 유형에 따라 명시적인 catch 블록을 먼저 사용하여 처리하는 것이 좋다.
예를들어 보자.
std::filesystem::filesystem_error는 <filesystem> 헤더에서 정의된 특정 예외 클래스로 파일 시스템 작업의 실패 원인에 대한 정보를 보다 자세히 제공한다. 이렇게 보다 구체적인 예외 클래스를 사용하면 예외를 더 쉽게 처리하고, 예외 객체에서 세부 정보에 접근할 수 있다.
#include <iostream>
#include <filesystem>
int main() {
std::filesystem::path sourceFile("path/to/source.txt");
std::filesystem::path destinationFile("path/to/destination.txt");
try {
std::filesystem::rename(sourceFile, destinationFile);
std::cout << "File moved successfully." << std::endl;
} catch (const std::filesystem::filesystem_error& e) {
std::cout << "Failed to move file: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cout << "exception : " << e.what() << std::endl;
}
return 0;
}
'프로그래밍 > C++' 카테고리의 다른 글
C++ ] Manipulator와 iomanip 헤더 (0) | 2023.05.28 |
---|---|
C++ ] static_cast와 reinterpret_cast. 그 외 const_cast, dynamic_cast (0) | 2023.05.28 |
C++ ] filesystem 라이브러리 (0) | 2023.05.28 |
C++ ] JSON 데이터 포맷, rapidjson 라이브러리 사용해 파싱 (0) | 2023.05.14 |
C++ ] stream 상속관계 (0) | 2023.05.14 |