문법 상 문제가 없지만, 실행시 오류가 발생했을 때 즉, 정상적인 상황에서 벗어난 모든 예외적인 상황들을 예외(exception)이라고 부름
char *c = (char *)malloc(1000000000);
if (c == NULL) {
printf("메모리 할당 오류!");
return;
}
throw
문을 통해 명시적으로 나타낼 수 있음Vector
클래스에서 at
함수를 작성한다 생각하자// 생략 ...
const T& at(size_t index) const {
if (index >= size) {
// 예외를 발생시킨다!
throw std::out_of_range("vector 의 index 가 범위를 초과하였습니다.");
}
return data[index];
}
// 생략 ...
};
throw
시 해당 위치에서 즉시 함수가 종료되고, 예외 처리하는 부분까지 점프하게 됨try
: 내부에 예외가 발생할만한 코드를 작성stack
에 생성된 모든 객체들의 소멸자들이 호출되고, 가장 가까운 catch
문으로 점프catch
: throw
된 예외를 받아 예외시 행동을 실행#include <iostream>
#include <stdexcept>
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
는 여러 종류의 예외를 받을 수 있어 한 개의 try
안에 받고자 하는 모든 종류의 예외를 catch
문으로 주렁주렁 달면 됨#include <iostream>
#include <string>
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;
}
}
#include <exception>
#include <iostream>
class Parent : public std::exception {
public:
virtual const char* what() const noexcept override { return "Parent!\n"; }
};
class Child : public Parent {
public:
const char* what() const noexcept override { return "Child!\n"; }
};
int func(int c) {
if (c == 1) {
throw Parent();
} else if (c == 2) {
throw Child();
}
return 0;
}
int main() {
int c;
std::cin >> c;
try {
func(c);
} catch (Parent& p) {
std::cout << "Parent Catch!" << std::endl;
std::cout << p.what();
} catch (Child& c) {
std::cout << "Child Catch!" << std::endl;
std::cout << c.what();
}
}
switch
문의 default
나 if-else
의 else
처럼 ...
를 사용하면 검색되지 않은 모든 예외를 처리 가능catch
에서는 모든 예외 객체를 고려해야 함 try {
func(c);
} catch (int e) {
std::cout << "Catch int : " << e << std::endl;
} catch (...) {
std::cout << "Default Catch!" << std::endl;
}
}
noexcept
를 통해 명시할 수 있음