열혈강의 13장 예외처리

---> 예외가 발생하는 지역과 처리되어지는 영역이 다른 경우

---> 기존 예외처리 방식은 예외가 방생하는 지역에서 해결을 한다.


1. 예외처리 메커니즘

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

+ Recent posts