예외처리-try-catch문 정리



예외처리- try-catch문 정리!!!


1.예외(Exception)란? : 프로그램의 정상적인 실행을 방해하는 조건이나 상태(에러X)
 

2.try-catch문?
=>try-catch문은  C++문법으로 언어차원에서 지원하는 예외처리 구문이다.
if-else문을 쓰다보니 가독성이 너무 떨어지고, 소스가 반복이 많아서 너무 비효율적이다.
그래서 예외처리 문법을 제공하는 것이다.
이것은 라이브러리 수준이 아닌 언어 차원에서 새로운 예외처리문법을 제공하는 것이다.

try: 예외가 발생할만한 코드 블록을 지정
      try{} 괄호 안에 예외 처리 대상 코드를 작성한다.
      이블록안에서 예외가 발생했을 때 throw 명령으로 예외를 던짐.

throw: 프로그램이 정상적으로 실행될 수 없는 상활일 때 이 명령으로 예외를 던진다.
   thorw다음에 던지고자하는 예외객체를 넘김. 예외 던지면 catch문으로 이동
            (단: 예외 객체 타입이 맞을때만 적용됨 ), (오버로딩 가능)

catch: if-else문처럼 try-catch문으로 한쌍으로 쓰인다.
           try안에서 throw한 예외 객체에 대한 예외처리를 한다. catch블록을 예외 핸들러라고 부른다.
 


try{
    if(예외조건)
       throw 예외객체;
} catch ( 타입 예외객체 ){
      예외처리;
}



주의할점: 
1.catch문은 예외가 발생될때만 실행 되므로 읽을땐 없다고 봐도 무방함!(가독성이 증가한다!!!)
2.catch문은 오로지 throw 로만 이동이 가능하고, goto문으로도 불가능.
3.catch문은 여러개 만들수 있다.(오버로딩과 비슷?!?! 하다.) 
4.예외가 발생할만한 코드가 try안에 있어야되는데 없으면 throw시 catch문을 못찾아 에러남
또한, throw했는데 객체타입을 catch문에서 받아줄 수 없을때 에러남

=>오버로딩과의 차이점은 함수 오버로딩은 매개변수종류와 갯수 const유무의 따라서 일치하는 함수가 바로 호출되지만
catch문은 switch문처럼 제일 첫번째 예외부터 순차적으로 비교가 이루어지고 결정난다!
---------------------------------------------------------------------------------------------------------------

3.스택되감기(Stack Unwinding)
try-catch 문에서 try{}블럭안에서 함수가 불리고 그 함수에서 throw를 한다고 가정해보자.
그럼 throw 를 하게 되면 어떻게될까?
그냥 goto문처럼 이동하는것일까?
ex) 
void Func()
{
     //어쩌구저쩌구~
     int a;
     throw a; 
}

try{
    Func();
}catch( int i ){
     //어쩌구저쩌구~
 
=> 답은 X 아니다이다!
스택프레임에 쌓여있던 try{}안에서 함수를 호출한 호출원을 찾아 자기 자신의 스택을 정리한다.
이것을 스택 되감기(Stack Unwiding) 이라고 한다.


4. try-catch구문은 중첩이가능하다!
이럴때 만약 예외객체 타입이 겹친다면 그냥 throw를 쓰기만 하면 상위에있는 try-catch문의 같은 타입 catch문으로 들어간다( 말이 너무 어렵나?..) ㅋㅋ


5.예외클래스
보통 함수리턴값으로 예외처리를 많이 하는데, C++은 try-catch문을 사용하므로 리턴값을 다른용도로 쓸 수 있어 아주 좋다.!!

<예외처리하는 여러가지 방법들>
1) 이넘값을 만들어서 함수 리턴값을 이용한다.
2) 이넘값을 만들어서 try-catch문을 이용한다.
3) 그냥 예외처리하는 클래스를 만들고 throw 할때 클래스를 보낸다!(예외 클래스)
   이렇게 예외클래스 사용하면 클래스를 복사해서 보내기때문에 catch문에서 레퍼런스로 받는게 좋다!!

tip)
보통 예외 클래스는 멤버변수가 int menu를 가지고 있어서 
함수로 switch( menu )식으로 조사하는 방법이다!
그래서 throw로 넘길때 throw SK( 1 ), throw SK( 2 ) 이런식으로 넘김



*예외 클래스 사용 하는법
보통 class안에서 예외처리코드를 모두 포함하는것이 바람직하다.
보통 지역클래스를 이용한다.(그 지역안에서만 사용 가능하니.. 와우)


6. 예외처리기능은 생성자와 연산자에도 쓸수 있다.(중요)
이게 무슨의미가 있냐면 보통 함수는 리턴값이 있어서 예외처리를 쉽게 할 수 있지만,
생성자는 리턴값이 없고, 연산자는 리턴값이 있지만 항상 의미가 있는 값이라 사용할 수 없는데
try-catch문은 리턴값을 이용하는게 아니라 throw 를 이용하는것이라 생성자,연산자에서 사용하는것이 엄청난 장점!!!

정리하면 예외는 
try 문에서 그냥 던질수도 있고, try문에서 함수안에서 던져질수도있고, try문안에있는 생성자나 연산자로도 예외를 던지는 것이 가능하다.


*함수안에서 try-catch문
void func()
{
   try{
   }catch{
   }
}


void func()                //함수자체의 괄호가 사라졌다!!!!!!!!!!!!!!
   try{
   }catch{
   }

이렇게 표현이 가능하다!!!!( 함수의 괄호를 안써도 가능!!! 이 기능은 생성자에서 중요하게 쓰임 ) 


참고로:예외객체는 암시적 변환을 하지 않는다.


7.예외지정
함수를 작성할 때 함수의 원형 뒤쪽에 이 함수 실행중에 발생할 수 있는 예외의 종류를 지정할 수 있다!!!
인수목록다음에 throw(타입) 이렇게 써주면된다.
->함수의 원형 뒤에 throw는 안써줘도 된다 근데 throw로 예외 종류를 알려주는것은
일종의 문서화로 사용하는 사람에게 예외가 발생할 수 있는지를 알려주며 일종의 주석같은 역할을 하는것이다!!!! 
 

즉! 리턴값 함수명(매개변수들) throw(예외객체들들들)
ex) 
void Func(int temp) throw(char*);
void Func(int temp) throw(char*, int);
void Func(int temp) throw(char*, int , char);
void Func(int temp) throw();           //이 함수의 의미는? =>예외를 절대로 안던진다는 의미!!!
void Func(int temp);          //이 함수는 => 예외를 던질수도 있고, 안덜질수있다.



8.try-catch문의 단점
1. 프로그램의 성능이 눈에 띄게 느려진다(스택되감기 기능만 생각해도 알만함~)
2. try-catch를 쓰게 되면서 프로그램 용량이 커지게된다.( 소스길이가 증가함 )
3. 전통적인 if-else 문을 모조리 바꿀 수 없다( 못바꾸는 예가 있다 )
4. 동적할당한 메모리가 해제안될 수 있다.( throw때문에 )
5. 템플릿에는 쓸 수 없다.( 예외 객체에 어디에 받아야 하는지 모르기때문!! )


9.결론:
try-catch문은 언어차원에서 지원하는 참 좋은 예외처리구문이지만 단점도 존재한다. 잘 조절해서 꼭 필요한곳에서 쓰도록 하자!







하악~
진리의 www.winapi.com C++부분의
예외처리부분 보고 정리했음!

역시 난 김정리~
 

<추가한 내용> 

1. 예외처리만의 클래스가 있을때는 주의해야될것이 상속됫을 경우이다!
catch 문은 순차적으로 catch문 예외인자를 순서대로 진행된다!
그렇기때문에 상속된 자식클래스부터 적어줘야한다.( 부모는 자식을 받을 수 있기 떄문에 )

2. catch 문안에 예외인자는 그냥 타입만 적어줘도 가능하다!

이 글을 공유하기

댓글

Designed by JB FACTORY