씹어먹는 C++
12장 c++에서의 예외 처리 613p-629p
정상적인 상황에서 벗어난 모든 예외적인 상황
문법 상 틀린 것이 없는 코드라도 실제로 실행 시 오류발생 가능성 있음
예외가 발생 사실을 명시적으로 나타냄
example code
const T& at(size_t index) const {
if (index >= size) {
// 예외를 발생시킨다!
throw std::out_of_range("vector 의 index 가 범위를 초과하였습니다.");
}
return data[index];
}
try
무언가 예외가 발생할만한 코드가 실행
catch
throw 된 예외를 받는 부분
정의된 예외의 꼴에 맞는 객체로 받음
template <typename T>
class Vector {
public:
Vector(size_t size) : size_(size) {
data_ = new T[size_];
for (int i = 0; i < size_; i++) {
data_[i] = 3;
}
}
const T& at(size_t index) const {
if (index >= size_) {
throw std::out_of_range("vector 의 index 가 범위를 초과하였습니다.");
}
return data_[index];
}~
Vector() { delete[] data_; }
private:
T* data_;
size_t size_;
};
int main() {
Vector<int> vec(3);
int index, data = 0;
std::cin >> index;
try {
data = vec.at(index);
} catch (std::out_of_range& e) {
std::cout << "예외 발생 ! " << e.what() << std::endl;
}
// 예외가 발생하지 않았다면 3을 이 출력되고, 예외가 발생하였다면 원래 data 에
// 들어가 있던 0 이 출력된다.
std::cout << "읽은 데이터 : " << data << std::endl;
}
catch 로 점프 하면서 스택 상에서 정의된 객체들을 소멸
각 객체의 소멸자 호출하여 소멸
catch문
여러 종류의 예외들을 받기 가능
각기 다른 타입으로 throw 하면 작동하는 catch가 달라짐
example code
int func(int c) {
if (c == 1) {
throw 10;
} else if (c == 2) {
throw std::string("hi!");
} else if (c == 3) {
throw 'a';
} else if (c == 4) {
throw "hello!";
}
return 0;
}
int main() {
int c;
std::cin >> c;
try {
func(c);
} catch (char x) {
std::cout << "Char : " << x << std::endl;
} catch (int x) {
std::cout << "Int : " << x << std::endl;
} catch (std::string& s) {
std::cout << "String : " << s << std::endl;
} catch (const char* s) {
std::cout << "String Literal : " << s << std::endl;
}
}
어떤 예외를 throw but, 받는 catch 가 없을 수 있음
example code
int func(int c) {
if (c == 1) {
throw 1;
} else if (c == 2) {
throw "hi";
} else if (c == 3) {
throw std::runtime_error("error");
}
return 0;
}
int main() {
int c;
std::cin >> c;
try {
func(c);
} catch (int e) {
std::cout << "Catch int : " << e << std::endl;
} catch (...) {
std::cout << "Default Catch!" << std::endl;
}
}
명시적으로 함수가 예외 발생 시키지 않음을 표현
int foo() noexcept {}
물론 키워드가 있다 해서 반드시 예외를 던지지 않지는 않음
만약 예외를 던지게 예외가 처리되지 않고 비정상 종료됨