■ 항목13 자원 관리에는 객체가 그만!

생성한 자원에 대해서 빠짐없이 해제하기 위해서는 c++에 소멸자를 이용하면 제격이다.
스택에서 사용하는 메모리나 non static 영역에 생성된 메모리라 할지라도 scope에 상관없이 결국 자동으로 해제가 되어 자원 누수에 대한 걱정을 하지 않아도 된다.
STL에 auto_ptr이란게 바로 그것이다.
이름에서도 알수 있듯이 auto 변수 처럼 블록을 벗어날때 자동으로 소멸되는 포인터에 대해서 자동으로 해제 동작을 수행해 주는 것이다.
void f()
{
  std::auto_ptr<Investment> pInv( createInvestment()) ;
...
// pInv는 이 함수를 벗어날때 자동으로 소멸된다.
}
자원 관리 객체의 2가지 특징
■ 자원을 획득한 후에 자원 관리 객체에게 넘겨라
위에서 createInvestment() 즉 객체를 생성함과 동시에 pInv에 복사 생성자를 이용해서 초기화했다.
이것을 자원획득초기화(Resource Acquisition Is Initialize: RAII)라 한다.
■ 자원 관리 객체는 자신의 소멸자를 사용해서 자원이 확실히 해제되도록 한다.
auto_ptr사용시 주의점
auto_ptr의 소멸자에서 자원을 해제하기 위해서 delete를 사용한다.
둘이상에 auto_ptr이 같은 자원을 가리키게 되면 해제된 자원에 delete가 수행되게 되어 미정의 동작이 수행되게 된다.
  이걸 방지하기 위해서 auto_ptr에 복사가 일어날 경우 복사가 된후에 원본에 자원은 null처리된다.
// 생성
std::auto_ptr<Investment> pInv1( createInvestment()) ;
std::auto_ptr<Investment> pInv2(pInv1) ;
// 이시점에 pInv1이 가르키는 자원은 null처리된다.
pInv1 = pInv2 ;
// 이시점에 다시 pInv2가 null처리
즉 auto_ptr을 container에 담는 동작은 하지 마라.
이럴때는 참조↑↑카운팅방식에 스마트 포이터(reference-counting smart pointer)를 사용해라
void f()
{
  std::tr1::shard_ptr<Investment> pInv1( createInvestment() ) ;
  std::tr1::shard_ptr<Investment> pInv2(pInv2) ;
  // 이시점에 pInv1, pInv2는 같은 자원을 가르키며 참조카운트만 증가
  pInv1 = pInv2 ;
  // 이시점에는 아무변화 없다.
// scope를 벗어날때 reference count = 0일때 소멸
}
또하나 array같은 자원에 대해서도 delete만을 수행하기 때문에 자원 누수가 생길 수 있다.
이를 위해서 boost::scoped_array, boost::shard_array가 준비되있다.

EOF

+ Recent posts