이번 항목은 생성자에서 어떻게 예외가 발생 될 수 있으며, 생성자에서 예외가 발생한것이 어떤 의미인지 살펴 보는 항목이다.

예제 코드

질문 1. 예제 1에서 생성자에서 예외가 발생하면 어떻게 잡을 수 있을까?

질문 2. 예제 2에서 객체의 수명을 설명 할 수 있는가?


해설


1. 예외 발생 어떻게 잡을 수 있는가?

질문에 대해서만 답하자면, 예외를 잡기 위해서 try catch 문을 사용 해야 할것이다. 코드로 옮기자면,

이렇게 try catch 문을 사용 할수 있다. 유념해야 할것은 1. try 문 자체가 생성자의 초기화 목록 위쪽에 배치하고 생성자 본문 구역을 다 감싸고, 다음 catch( ... ) 로 넘겨야 할 것, 2. catch(...) 에 들어 오게 되면, A의 생성자가 성공했다면, A::~A() 가 호출된 상태이다.

경우 를 생각하자면

  1. A의 생성자 성공하고 b의 생성자가 실패해서 catch에 들어감
  2. 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++ 에 비해서, 설명 방식이 달라 읽는게 꺼려졌지만, 지금 다시 읽어 보니, 농담도 있고, 재미있게 볼 수 있고, 잘 되었다.

posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요