이번 항목은 개체의 지금 존재 하는가? 존재 하지 않는가? 를 생각하게 한다. 개체가 존재하지 않은데 접근을 하면 에러가 날 수 있듯이, 어떨 때 달라지는지에 대해서 알아보자.


이 코드의 #2 부분은 합법 적인가?

분석
이 코드는 합법적(문법이)이며, new (&t) T(2); 예외를 발생되지 않는 다면 매우 안전한 코드이다.^^

여기서 짚고 넘겨야 하는 것은 t.~T(); 호출 후 ~ new (&t) T(2); 완료전까지 t나 rt 를 사용 할수 없다. 그리고 T::operator&() 의 경우 주소값 외에 어떤것을 부수적으로 실행 되어서는 안된다.

분석 초기에 말했다 시피, 이 코드는 합법적이지만, new (&t) T(2);에서 예외가 발생되었을 경우, 예외 전달이 될 것이다. 하지만 여기선 예외 처리가 없으므로, f() 의 스택을 풀어버리게 될 것이고 t.~T()는 다시 호출 하게 된다. 이 때, 코어 덤프나 예상치 못한 결과가 일어 날 수 있다.

가이드 라인
항상 예외 안전성을 가진 코드를 만들려고 고려하자. 단 한번의 예외로 모든 프로그램이 망가질 수 있기 때문이다.

 

여기서 프로그래머의 자만심이 나중에 큰 문제를 겪게 될 수 있다. 이 자만심은 콕 찝어 말한다면, 개체 T가 소멸 되고, 다시 생성될 것이라고 믿는 자만심 이다.

만약 이것이 멤버 함수속에 들어가 클래스의 객체를 초기화 된다고 짠다면 어떻게 될까?


 

몇가지 가정을 내려 보자.
1. /*AAA*/ 가 T이고, /*BBB*/가 T의 부모일 경우,

T::~T() 호출시 T의 부모 소멸자도 호출되면서 T와 T의 부모도 파괴된다. T의 상태 변화로 인하여, T의 부모 변수도 변경된 상태라면, T의 부모는 그 값에 대한 상태가 아닌 경우가 되므로 부모의 데이터를 보증 할 수 없게 된다.

2. /*AAA*/ 가 U이고, /*BBB*/가 T일 경우

U가 T를 포함되는 메모리 구조로 될 것이다. 이때 T::~T() 소멸자 호추로 인하여, T 메모리에 있던 것들이 파괴도고 그 자리에 T 객체를 생성 하게 되는데, 이런 작업은이 사용 가능한 지에 대해서 알 수 없다. 왜냐하면 컴파일러마다 그 작업을 어떻게 진행 시키는지 알 수 없기 때문이다.

MSVC2005 에선, 예외만 발생되지 않으면 .. 소멸자 호출 후에도 객체 접근 및 값 변경도 잘 처리 된다; 다음의 예제코드를 한번 컴파일 해 보길...

가이드 라인
언어의 잘 모르는 부분은쓰지 않는것이 가장 효율 높은 코드를 만드는데 초석이 된다.


총평

역시 미묘한 문제이다. 컴파일러마다 특성이 타고(.. 증명은 못했다. 단지 책에서 알수 없다 는 문구로 추측을 한것이고 MSVC2005에선 성공을 했기에 추측 할수 이었다.), 예외에 안전하지 못한 코드 이므로, 조심해야 할 것이다.

또한 메모리 지정 할당 new 에 대해서 컴파일 하기 위해선 #include <new>가 필요 하다는 부분도 알게 되었고, 서버에서 응용하여 메모리 할당 및 초기화에 쓸 수 있을 것이라고 생각 된다.

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