오류
오류에는 다양한 종류가 있다. 컴파일 과정에서 문법에 맞지 않아 오류가 발생할 수도 있고, 코드 작성 과정에서 개발자의 실수로 개발자의 의도와 다르게 작동하는 오류도 있다. 혹은 논리적 오류로 인해 개발자가 예상한 범위에서는 정상적으로 작동하지만 특정 상황에서 오류가 발생하는 경우도 있다.
컴파일 오류나 개발자의 의도와 다르게 작동하는 오류의 경우는 따로 수정이 필요하지만, 개발자가 예상한 범위에서는 정상 작동하는 코드의 경우 개발자가 의도한 범위 안에서만 동작하도록 하고 그 외 부분은 예외처리하여 코드를 사용할 수도 있다.
예를 들어 거듭제곱을 계산하는 power라는 함수를 만들었다고 해보자. 근데 이 거듭제곱을 계산하는 함수는 정수에 대한 양의 정수 제곱밖에 계산하지 못한다면 실수의 거듭제곱 혹은 음수 제곱을 못한다는 이유로 사용하지 않는 것이 아니라 정수와 양의 정수 제곱이 주어졌을 때만 계산하도록 하고, 그 외 입력이 들어올 때는 예외처리 하여 사용자에게 알리는 것으로 코드를 작동시킬 수 있다는 이야기이다.
가장 간단하게는 예외가 발생했을 때 반환값을 특별한 값으로 지정하여 그 경우 따로 출력을 내보낼 수 있다.
예외 처리
개발자가 인지할 수 있는 예외들은 try-throw-catch 문을 이용하여 처리할 수 있다. try 블록에 예외가 발생할 가능성이 있는 코드를 넣고, 예외가 발생하면 throw를 통해 catch로 전달한다. catch 블록은 예외가 발생했을 때 동작할 코드가 정의된다.
try {
...
if (예외 발생 상황) {
throw 예외;
}
...
} catch (예외 처리할 파라미터 선언) {
...
} catch (예외 처리할 파라미터 선언) {
...
}
예를 들어 앞서 언급한 두 수를 입력받고 거듭제곱을 계산하는 함수를 예외 처리를 하여 다음과 같이 정의할 수 있다.
long long power() {
try {
cout << "a^b를 계산합니다.\na와 b를 입력하세요: ";
int a, b;
if (not (cin >> a)) {
cin.clear();
cin.ignore(MAX_SIZE, '\n');
throw "입력 오류";
}
if (not (cin >> b)) {
cin.clear();
cin.ignore(MAX_SIZE, '\n');
throw "입력 오류";
}
if (b < 0) {
throw "b는 음수가 될 수 없습니다.";
}
long long ans = 1;
for (int i = 0; i < b; i++) {
ans *= a;
}
return ans;
} catch (const char* e) {
cout << e << endl;
return -1;
}
}
혹은 아래와 같이 아예 예외 처리를 함수 밖에서 처리할 수도 있다. 예를 들어 아래와 같이 위 코드를 수정하면 예외 발생시 함수를 호출한 곳으로 돌아가 예외를 처리한다.
long long power() throw(const char*) {
cout << "a^b를 계산합니다.\na와 b를 입력하세요: ";
int a, b;
if (not (cin >> a)) {
cin.clear();
cin.ignore(MAX_SIZE, '\n');
throw "입력 오류";
}
if (not (cin >> b)) {
cin.clear();
cin.ignore(MAX_SIZE, '\n');
throw "입력 오류";
}
if (b < 0) {
throw "b는 음수가 될 수 없습니다.";
}
long long ans = 1;
for (int i = 0; i < b; i++) {
ans *= a;
}
return ans;
}
당연히 클래스의 멤버 함수도 같은 방식으로 예외 처리를 해줄 수 있다.
예외 클래스
만약 throw로 예외 값을 던질 때 int, char 등 기본 자료형 말고 객체를 던지고 싶다면 예외 클래스를 만들어 던지면 된다. 예외 클래스는 기본적인 클래스와 똑같이 만들면 되고, throw를 이용해서 던질 때 생성자를 이용해서 객체를 생성한 후에 던지면 된다.
'Language > C & C++' 카테고리의 다른 글
[C++] 파일 입출력 스트림(file I/O stream) 및 파일 포인터(file pointer) (0) | 2024.12.06 |
---|---|
[C++] 포맷 플래그(format flag) 및 조작자(manipulator) (0) | 2024.12.04 |
[C++] 입출력 스트림(I/O stream) 및 버퍼(buffer) (0) | 2024.12.04 |
[C++] 람다(lambda) 표현식 (0) | 2024.11.15 |
[C++] auto 키워드 (0) | 2024.11.14 |