2008.10.10 03:20 책 정리/Exceptional C++

이번 항목은 표준 auto_ptr을 안전하고 효율적으로 사용하는 방법에 대한 기본적인 것들을 다룬다.

C++ 세계에 있어, 이번 항목은 좀 특별하다. 왜냐하면 최종 C++ 98 표준안 : "Final Draft International Standard for Programing Language C++"이 완벽하게 결의되는 마지막 모임이 시작되는 전날에 auto_ptr의 이 문제점이 알려 졌기 때문이다.

그렇다면 이 문제가 무엇인지 알아보자!

 

문제 : 자 어디가 좋고, 안전하고, 합법적인가? 혹시 그렇지 않나?

 

 

분석

이 책이 쓰여진 당시 auto_ptr은 신기한 smart_ptr 일 것이다. 하지만 지금은 2008년 최소한 10년은 됬다. 그러므로 auto_ptr의 사용 법에 대해선 생략(사용법에 대한 내용은 쉽게 찾을수 있기 때문이다)하고, 어디에 쓰이는가에 대한 분석만 한다.

분석에 앞서 auto_ptr이 어떤 녀석인지 알아보고 어디에 쓰일수 있는지 생각해 보자.

  1. auto_ptr은 소유권 개념이 있는 smart_ptr 이다.
  2. auto_ptr은 포인터를 Scope로 감싸는 형태를 취한다. 이것은 객체의 활동 범위처럼 속박할 수 있게 해 준다.
  3. auto_ptr 의 내부 연산은 예외가 발생하지 않는 연산( 기본 타입의 복사 할당 및 복사 생성 )으로 이루어졌다.

1번은 그렇다 치고, 2번을 생각한다면, 함수 내부에서 동적 메모리 할당 할 필요가 있다면, 쓸만 하겠다. 3번을 생각한다면, 강력한 예외 안전성(절대 예외를 발생하지 않는다)을 가지고 있다. 그렇다면 이 경우에 합당한 경우가 어떨때 있을까? 다음 코드를 보자.


이 코드에서 f를 유심히 보면 Temp_Str 을 만들고, 거기에 "천재" 나 "바보"를 할당하고, Temp_Str 을 임시객체로 복사 할당하면서 리턴 된다. 그런데 만약 임시 객체로의 복사 할당에서 예외가 발생한다면, 예초에 "천재"든 "바보"든 연산 될 필요가 없다.  강력한 예외 안전성을 보장하는 연산으로 넘길 방법이 없을까? 그렇다 .. 포인터 할당 연산자를 통하여 넘기면 될 것이다. 하지만 포인터 할당 연산자는 Scope가 없어, 천재와 바보로 분기 연산 시, 예외가 발생하면 메모리를 잃어 버리게 된다.

 

해결 방법이 나왔다. 포인터에 지역 Scope를 먹여주면 된다! 그것이 바로 smart_ptr 의 일종인 auto_ptr 이다! 위의 코드를 다음과 같이 변경을 해보면, 완벽한 해결이 된다.


 

해왕기의 주인공 "판 감마 비젠"이 이 코드를 보고 엄마에게 일러 버릴 법 한 강력하고도 효율적인 코드로 완성 되어 진다.

 

허브 셔터는 이 외에도 쓸만한 기법으로 const std::auto_ptr<T> 기법을 소개 했다. 객체에 const 를 넣는다는건 그 메소드 모두다 const 속성을 부여하게 됨으로써, 오로지 get() 연산만 외부에서 쓸 수 있게 된다. 다음 코드를 보며 어디에 쓰일수 있는지 생각해 보자.

오호호~ 그렇다, auto_ptr의 소유한 객체는 변화해도 되지만, auto_ptr 자체가 변경이 되는 모든 것들은 막아 버린다. 이것은 const 키워드로 컴파일 타임에 그 강력한 자물쇠로 잠궈 두었다. 이것의 이용은 절대 소유권을 양보하지 않을 때가 될 것이다.^^

 

총평

auto_ptr을 이용한 성능 향상(물론 new로 성능이 깍이는 부분이 있으나 그 효력에 비한다면, 그냥 줘도 될 법 하다)과 강력한 예외 안전성을 보장하는 것을 보고 감명을 받았다. 최고다. 이런 사용을 보는것보다 사용을 하게 된 알고리즘을 배워야 한다. 일명 "판 감마 비젠" 알고리즘 이라 칭한다. ㅋㅋ

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

댓글을 달아 주세요