---> 예외가 발생하는 지역과 처리되어지는 영역이 다른 경우
---> 기존 예외처리 방식은 예외가 방생하는 지역에서 해결을 한다.
try {
if(){ //예외 발생 예상 지역
throw ex; --> ex를 가리켜 '예외'라고 표현한다. 예외상황이 발생됨을 알려주기 위해 사용되는 키워드
}
}
catch(처리 되어야 할 예외의 종류){ --> 위 try 블록의 ex가 전달된다.
//예외를 처리하는 코드
}
int main(){
int a, b;
cin >> a >> b;
try{
if(b==0) throw b; ----> 예외가 발생하면 b가 catch로 전달 된다.
.... -----> 예외가 발생하면 try블록안의 다음 문장들은 실행되지 않고 catch가 실행된다.
.... -----> 반대로 예외가 발생하지 않으면 catch가 실행되지 않고 try블록을 끝까지 실행하게 된다.
}
catch(int exception){
cout<<exception<<"을 입력했습니다."<<endl;
cout<<"입력 오류! 다시 실행 하세요."<<endl;
}
}
2. Stack Unwinding (스택 풀기)
int divide(int a, int b);
int main(){
int a, b;
cout <<"두개의 숫자 입력 : "; cin >>a>>b;
try{
cout<<divide(a,b)<<endl;
}
catch(int exception){
....
....
}
}
int divide(int a, int b){
if(b==0) throw b; ----------> b가 diveide가 호출되는 영역으로 넘어간다.
return a/b;
}
////////////////////////////////////////////////////////////////////////
int main(){
try{
divide();
....
}
catch(int ex) { .... }
}
int divide(){ divide2(); }
int divide2(){ divide3(); }
int divide3(){
throw b; -------->
}
스택
divide3() ---> 예외 발생 throw b; try catch 블록이 없네? 자신을 호출한 함수를 찾아간다. ---> 전달해주면서 할당된 스택영역 해제
divide2() ---> b를 전달 받음. try catch 블록이 없네? 자신을 호출한 함수를 찾아간다. ---> 이 또한 마찬가지
divide1() ---> b를 전달 받음. try catch 블록이 없나? 자신을 호출한 함수를 찾아간다. ----> 이 또한 마찬가지
main() ---> b를 전달 받음. try catch 블록이 있네? 예외처리 실행.
3. ex
1. throw 를 통해 예외를 전달 했으나 어디에도 try catch 블록이 없을 때 --> abort()함수가 호출.
--> 예외는 반드시 처리되어야 한다!!
2. throw b; ---> b는 int 형
catch(char ex) { ... } --> abort()함수가 호출된 --> 발생되는 타입과 처리되어지는 타입이 같아야 한다.
3. throw (int, double, char*) ---> int , double, char* 형태로만 예외를 발생시키겠다!!
4. throw --> 다양한 타입으로 예외를 발생시킬 경우
catch(char exp){ ... }
catch(int exp) { ... }
---> 함수 오버로딩의 형태가 아니라 순차적으로 물어보면서 자기 타입에 맞는 catch를 찾는다.
3. 예외 클래스 디자인
--> 예외는 클래스의 객체로 표현되어 지는 것이 일반적이다.
--> throw 예외객체 --> 일반적인 형태 --> 객체로 표현되어질 경우 예외가 왜 발생되어 졌는지에 대한 상황을 충분히 담을 수 있다.
------------------------------------------------------------- 주의 사항
class AAA{}
class BBB : public AAA{}
class CCC : pubic BBB {}
int main(){
try{
throw AAA();
throw BBB();
throw CCC();
}
catch(AAA& ex) { ... } ---> 위의 세 경우 모두 이 블럭이 실행된다. 왜?? is-a관계에 의해 derived클래스가 모두 처리되어 질 수 있기 때문이다. (CCC는 AAA다가 성립)
catch(BBB& ex) { ... } ---> 해결챌은 간단하다. catch의 순서를 거꾸로 해주면 된다.
catch(CCC& ex) { ... } ---> AAA는 CCC이다가 성립하지 않기 때문에 AAA는 자신의 catch를 찾아 마지막까지 내려오게 된다.
}
-->throw AAA() --> 임시객체로 던졌는데 어떻게 참조 형식으로 받을 수 있지? 임시객체는 다음 줄이면 바로 없어져 버리는 거 아닌가?
'C++' 카테고리의 다른 글
[C++] 팩토리 함수 (0) | 2016.12.19 |
---|---|
[C++] API란? (0) | 2016.12.15 |
[C++] 템플릿 // 열혈강의 (0) | 2016.12.12 |
[C++] 복사생성자 정리 (0) | 2016.12.07 |
[C++] 레퍼런스 정리 (0) | 2016.12.07 |