블로그 이미지
이태원에서 사는 다섯식구의 무직 가장. 흰둥에미

카테고리

분류 전체보기 (184)
Itaewon (2)
ryu's?? (1)
20121210이전 (20)
20130827이전 (147)
soo'study (13)
Total35,270
Today14
Yesterday4

항목8. auto_ptr의 컨테이너는 절대로 만들지 말자.

- auto_ptr의 참조카운팅을 하나만 지원, 즉 auto_ptr의 객체가 대입, 복사등이 이루어지면, 소유권이 바뀌어 버림.

- STL의 많은 기능이나 동작들은 객체 복사를 통해 이루어짐.

- 따라서 COAP(Container Of Auto Ptr)은 절대 금지.

  auto_ptr<Object> pObj1(new Object);
  auto_ptr<Object> pObj2(pObj1);        // pObj1에 있던 객체를 pObj2가 가리키고, pObj1은 NULL로 세팅됨.
  ...
  pObj1 = pObj2;                                // pObj2에 있던 객체를 pObj1가 가리키고, pObj2은 NULL로 세팅됨.

  - 위와 같은 상황 이전에, 코드 이식성이 보장되지 않음.

  - 스마트 포인터가 필요하다면, STL고 잘 섞어 쓸 수 있는 스마트 포인터를 구해서 써야함.

신고
Posted by 흰둥에미

항목7. new로 생성한 포인터의 컨테이너를 사용할 때에는 컨테이너가 소멸되기 전에 포인터를 delete하는 일을 잊지 말자.

- STL 컨테이너는 typedef로 정의된 value_type을 통해 관리하고 있는 데이터의 타입을 알려줌.

  new로 할당된 객체를 가리키는 포인터를 컨테이너에 담는 경우에는 직접 객체의 소멸이 이루어져야 함.

  for루프로 객체 소멸시키는 코드를 for_each로 바꾸기 위해선, 객체 소멸을 위해 delete하는 부분이 함수 객체(또는 함수)로 바꿔야함.

  template<typename T>
  struct DeleteObject; public unary_function<const T*, void>
  {
       void operator () (const T* ptr) const
       {
           delete ptr;
       }
   };
   for_each(vop.begin(), vop.end(), DeleteObject<Object>());   

   - 위와 같은 코드에서 가상 소멸자 없이 public 상속한 클래스에 대해서 DeleteObject<Parent>형으로 수행시, 문제 발생할 수 있음.

     템플릿 대상을 DeleteObject에서 operator()로 옮기면 해결 가능.

  

  struct DeleteObject
  {
       template<typename T>
       void operator () (const T* ptr) const
       {
           delete ptr;
       }
   };
   for_each(vop.begin(), vop.end(), DeleteObject());   

   - 템플릿 대상을 DeleteObject에서 operator()로 옮기면서, 어느 정도의 안전성은 확보되었으나,

     위 for_each문을 호출하지 못한다면(예외 등에 의해) 메모리 누수가 발생할 수 있음.

   - 결과적으로 포인터의 컨테이너를 쓰려거든, 괜찮은 상황이라면 스마트 포인터의 컨테이너로 바꾸라는 것

   - 단 컨테이너 자체를 스마트 포인터로 만들려고 하는 것은 잘못된 생각임.


신고
Posted by 흰둥에미

최근에 달린 댓글

최근에 받은 트랙백

글 보관함