다시 Stack 템플릿 클래스를 가져 온다.

문제 : 이제 예외에 안전한 복사 생성자와 복사 할당자를 만들어 보아라.

곰곰히 생각해 보면 복사 생성자와 복사 할당자는 서로 같은 로직이 들어 갈 수 밖에 없을 것이다.( 왜냐하면, 복사된다는 전제가 똑같이 깔리기 때문이다,) 그래서 복사하는 로직을 따로 만들어 두어, 복사 생성자와 복사 할당자에서 사용하면 좋을 듯 싶다. 다음 코드가 바로 그 코드 이다.

이 코드를 하나씩 분석하여, 어떻게 예외에 안전하게 처리 하는지 알아 보도록 한다. 우선 NewCopy로 들어온 매개변수 2,3번째로 복사 될수 있는지 assert 로 알아 보게 한다. (디버깅 모드에선 assert가 되지 않는 다는 것을 알아야 한다)

그리고 7라인, operator new[]() 를 이용하여 dest에 값을 넣는다. new 가 실패하면 예외 발생하고 dest에 아무것도 들어가지 않게 된다(전 항목 참조) 또한 T::T() 에서 예외를 던질 수 있으나, 전 항목에서 살펴본데로 객체 파괴되고 operator delete가 호출 되어 진다.

10 라인, copy 알고리즘은 내부적으로 operator= 을 이용하여, 값을 복사 하게 된다. 이때 operator=에서 예외가 발생 할수 있다. 그것은 12라인에서 받아서 처리 한다. catch( ... ) 은 모든 예외를 받는다.

14라인, 예외를 받았으니, dest를 전부 파괴 하고,
15라인, 발생된 예외를 다시 NewCopy 호출자에게 다시 반환해 준다. 즉, 예외에 중립적이다.^^(예외를 호출자에게 전달해 준다.)

17라인, 모드 성공했다면 dest를 반환한다. 이때 절대 예외는 발생하지 않는다.(기본 자료형은 예외를 리턴하지 않는다.)

복사 생성자


복사 할당자

여기서 중요한것은 복사 할당자에서 자기 복사 대입을 체크 하는 약한 감시 루틴이 추가 되었다. 그리고 절차적으로 본다면, 예외가 발생될 수 있는 상황까진 임시객체를 사용하고, 예외가 발생하지 않으면 다음 처리를 맞기는 구조로 되어 있는 것을 볼 수 있을 것이다.

다음 코드는 내가 만들어본 예외 안전 코드이다. 임시 객체를 이용해 swap을 하여, 원본의 데이터에 피해를 끼치지 않게 한다. 또한 operator= 에서 자기 복사에 대한 검사도 필요 없게 된다.

임시 객체를 이용하므로, 단지 자기 복사가 일어날 경우, ... 불필요하게 작동된다고 하지만 모든 operator=() 에 if로 검사하는 로직보다는 훨씬 깔끔 할 것이다.

문제로 남아 있는 것은 copy 알고리즘 사용시 그 범위 지정에 있다. 지금은 고정크기 10이지만, 후에 스택 크기가 변경될 경우, .. 그 범위에 맞게 맞추어야 한다.



총평
음.. 하나씩 추가 될때마다 조금씩 복잡해지는 경향을 보이고 있다. 더욱 예외처리에 대한 인식이 생겨난다고 해야 할까?
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기