이전 항목(15)에서 T의 요구사항 중 한가지인 소멸자에서 예외를 발생시키지 않아야 한다고 이야기 했던것을 기억 한다면, 왜 소멸자에서 예외를 발생 시키면 안되는지에 대해서 풀어 보도록 하자.

한가지 전제를 하여

T *p = new T[10];
delete[] p;

위의 코드드 중 소멸자에서 예외가 발생 된다면, 어떤 문제점이 발생 할 수 있을까?


첫번째, 만약 생성은 모두 성공하고 delete[] 처리 중 5번째꺼에서 파괴가 된다면 어떻게 될까?

5번째부터 10번째꺼는 파괴 불가능한 상태 되는 문제가 남는다. 이것은 p[0] 가 파괴 되었기 때문에 다시 delete[] p; 를 할 수 없기 때문이다.


두번째, 만약 생성 도중 예외가 발생하여, T의 소멸자를 호출해야 할 때, 예외가 발생 한다면, 어떻게 될까?

생성자 5번째 호출에서 예외가 발생되면, 4번째 객체에 대한 소멸자가 호출되어, 파괴 하고, 3번째 객체에 대한 소멸자에서 예외가 발생하면, 2번째와 1번째 객체는 파괴 시킬 수 없는 문제가 남게 된다.


결국 소멸자에서 예외를 던지게 되면, new[] 와 delete[] 둘다 사용하기 껄끄러운 상태로 되어 버린다. 유독 new[] 와 delete[] 만을 이야기 되는 것은 아니다.

만약 T의 소멸자에서 예외를 발생 시킨다면, 이 T는 함부로 상속도 HAS-A 관계도, 쓸 수 없는 노릇이 되고야 만다. 또한 STL 사용도 힘들어 진다. 부스트 사용도 힘들어 지고 .. 다 힘들어 진다. 결국 "소멸자에서 예외를 발생 시키지 않아야 한다." 라고  생각하고 코드를 짜는것이 더 편하고 더 안전하며, 더 길게 살 수 있는 요건이 되는 것이다.


총평

너무 매정한 예외 안전성 지키기, 기본 로직만 기억해 본다면, ..
  1. 임시객체에 모든 일을 적용 시키, 예외에 안전한 swap을 수행 시킨다.
  2. 소멸자에서 절대 예외가 일어나지 않게 한다.
  3. operator delete, operator delete[] 에서 절대 예외가 발생 되지 않게 한다.
로 요약 될 수 있겠다.





  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기