이번 항목은 생성자에서 어떻게 예외가 발생 될 수 있으며, 생성자에서 예외가 발생한것이 어떤 의미인지 살펴 보는 항목이다.
예제 코드
질문 1. 예제 1에서 생성자에서 예외가 발생하면 어떻게 잡을 수 있을까?
질문 2. 예제 2에서 객체의 수명을 설명 할 수 있는가?
해설
1. 예외 발생 어떻게 잡을 수 있는가?
질문에 대해서만 답하자면, 예외를 잡기 위해서 try catch 문을 사용 해야 할것이다. 코드로 옮기자면,
이렇게 try catch 문을 사용 할수 있다. 유념해야 할것은 1. try 문 자체가 생성자의 초기화 목록 위쪽에 배치하고 생성자 본문 구역을 다 감싸고, 다음 catch( ... ) 로 넘겨야 할 것, 2. catch(...) 에 들어 오게 되면, A의 생성자가 성공했다면, A::~A() 가 호출된 상태이다.
경우 를 생각하자면
- A의 생성자 성공하고 b의 생성자가 실패해서 catch에 들어감
- A의 생성자 실패하고 catch에 들어감
밖에 없다.
여기서 1번의 경우라면 catch( ... ) { /* 이곳 */ } <-- catch 블록 내에서 A의 소멸자 즉 A::~A() 를 호출하여, A 객체를 소멸시킨다. 2번의 경우라면 아무것도 생성되지 않았기에 그 어떤 소멸자도 호출하지 않는다.(예외 처리에 대한 로직을 제외한...)
잠깐,
1번의 경우라면, 책에선 catch( ... ) { /* 블록 내부 */ } 에서 소멸자를 호출한다고 하지만 MSVC2005 에서 블록 내부에 들어오기 전에 A의 소멸자가 호출 되어 객체를 파괴 한다. 다른 컴파일러는 테스트 해보지 못했다.
테스트 코드 : break point 찍어 봐서 테스트 해 보았음
내부에서 소멸자를 호출하던 외부에서 호출해서 들어 오던 결과적으로 의미를 놓고 본다면, 생성자가 정상적으로 종료되지 않으면, 아무 개체도 생성하지 않았다는 것을 뜻 한다.
생성자가 가지는 상속형 개체나, 멤버형 개체 들 중에서 예외가 발생했다면, .. 어딘가에서 예외가 발생했는지 판단하기 위해선 각 객체의 생성자에서 예외 안전성을 생각해보고 try catch 를 사용해야 할 듯 싶다.상속형이나 멤버형 개체 들 중에서 어떤 녀석이 예외를 발생시켰는지 파악하기 어렵기 때문이라고 보여진다.
2. 객체의 생명은?
객체 C는 9번 라인에서 생성자 본문이 실행되어 생성자 본문 } <-- 에서 완성 하게 된다. 소멸은 10라인 } <-- 소멸자가 호출되어져, 소멸자 본문이 실행되어, 소멸자의 } 가 끝나면서 파괴된다.
결국 { } 사이 중에서 선언된 곳에서만 생성이 부여되고 { } 에선 .. 메모리의 세계로 객체는 돌아가신 것 이다.
총평
대체적으로 .. 알던 사실이지만, 생성문에서도 try catch(...) 를 저렇게 할 수 있다는 것이 확인 되었다. 그런데로 재미있는 항목, 객체의 생성시 예외발생 잡기 위해선 좀 버거운 작업이 들어가야 될 듯 싶다.(예외 처리 자체가 워낙 .. 버겁다 보니.. ) 두번 읽어 보니 몰랐던 사항이다. : )
여담, Exceptional C++ 에 비해서, 설명 방식이 달라 읽는게 꺼려졌지만, 지금 다시 읽어 보니, 농담도 있고, 재미있게 볼 수 있고, 잘 되었다.
'책 정리 > More Exceptional C++' 카테고리의 다른 글
항목 39 : 네임스페스 Part 1 : using 선언과 using 지시자 (난이도 : 2) (1) | 2008.12.08 |
---|---|
항목 38 : typedef (난이도 : 3) (0) | 2008.12.08 |
항목 37 : 전방 선언(forward dclarations) (난이도 : 3) (0) | 2008.12.08 |
항목 36 : 초기화 (변수 초기화, 생성자의 문제점) (난이도 : 3) (0) | 2008.12.07 |
항목 23 : 예외 안전 클래스 설계 Part 2 : 상속 (난이도 : 6) (0) | 2008.12.06 |
항목 22 : 예외 안전 클래스 설계 Part 1 : 복사 지정 연산(copy assignment) (난이도 7) (0) | 2008.12.06 |
항목 21 : 관리되지 않은 포인터 문제 Part2 : auto_ptr은? (난이도 8) (0) | 2008.12.06 |
항목 20 : 관리되지 않은 포인터 문제 Part 1: 매개변수 (난이도 6) (0) | 2008.12.06 |
항목 19 : 처리되지 않은 예외 (0) | 2008.12.04 |
항목 18 : 생성자 실패 Part2 : 흡수? (0) | 2008.12.03 |
최근댓글