프로그래밍/Effective c++

14. 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자

CuriousBear 2016. 3. 10. 13:54
항목 13에서 자원을 객체가 관리하게 해주는 법에 대해 알아 보았다. 
하지만 힙에 할당되지 않는 자원은 스마트 포인터로 관리하기에 적절하지 않다. 이 경우 새로운 자원 관리 클래스를 만들어야 한다.
(라고 하는데 사실은 힙과 상관 없이 그냥 새로운 관리 클래스만드는 것에 대한 것인듯)

이 경우 객체가 복사 될때 어떤 방식을 취해야 할지 결정해야 하는데 보통 다음 4가지로 귀결된다.

Lock π11 (&m);
Lock m12 (ml1) ;

1. 복사를 금지. 객체가 복사되는 것 자체가 말이 안되는 경우가 많다. 이 경우 복사 연산을 private멤버로 지정하여 복사를 막는다.


2. 관리하고 있는 자원에 대해 참조 카운팅을 수행한다. - shared_ptr을 이용한다.
 
shared_ptr은 참조 수가 0이 되면 객체를 삭제시켜버리는데 이것을 수정할 수 있다.
다음과 같이 shared_ptr을 생성할 때, 삭제자를 우리가 원하는 함수로 넣어줄 수 있다.

class Lock {
public :
explicit Lock(Mutex* pm) : mutexPtr(pm, unlock )
{
     lock (mutexPtr.get() ) ;
}
private :
          std::tr1::shared_p tr mutexPtr; // 원시 포인터 대신에
} ;

3.  관리하고 있는 자원을 진짜로 복사한다. (깊은 복사)

4.  관리하고 있는 자원의 소유권을 옮겁니다. -> auto_ptr과 같은 방식
객체를 참조하는 RAII 객체는 딱 하나만 존재하도록 만들고 싶을 때 사용.

요약 + 추가
* RAII 객체의 복사는 그 객체가 관리하는 자원의 복사 문제를 안고 가기 때문에, 그 지원을 어떻게 복사 하느냐에 따라 RAII 객체의 복사 동작이 결정된다.

* RAII 클래스에 구현하는 일반적인 복사 동작은 복사를 금지하거나 참조 카운팅을 해 주는 선으로 마무리 하는 것이다.