KoreanFoodie's Study
Effective C++ | 항목 14 : 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자 본문
Tutorials/C++ : Advanced
Effective C++ | 항목 14 : 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자
GoldGiver 2022. 10. 25. 16:09
C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!
항목 14 : 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자
핵심 :
1. RAII 객체의 복사는 그 객체가 관리하는 자원의 복사 문제를 안고 가기 때문에, 그 자원을 어떻게 복사하느냐에 따라 RAII 객체의 복사 동작이 결정된다.
2. RAII 클래스에 구현하는 일반적인 복사 동작은 복사를 금지하거나 참조 카운팅을 해 주는 선으로 마무리하는 것이다. 하지만 이 외의 방법들도 가능하다!
우리가 직접 RAII 클래스를 만들어야 하는 다음과 같은 상황이 생겼다고 가정하자.
class Lock
{
public:
explicit Lock(Mutex *pm)
: mutexPtr(pm)
{ lock(mutextPtr); } // 자원 획득
~Lock() { unlock(mutextPtr); } // 자원 해제
private:
Mutex *mutexPtr;
};
...
// 사용하고 싶은 뮤텍스를 정의한다
Mutex m;
...
// 임계 영역을 정하기 위해 블록을 만든다
{
// 뮤텍스에 잠금을 건다
Lock m1(&m);
// 임계 영역에서 할 연산을 수행한다
...
// 블록의 끝에서 뮤텍스의 잠금이 자동으로 풀린다
}
위의 예시는 잘 동작할 것 같지만, 아래처럼 Lock 객체가 복사되는 경우에는 어떻게 작동할까?
Lock ml1(&m);
// ml1 을 ml2 로 복사. 어떻게 되어야 할까?
Lock ml2(ml1);
아마 대부분의 경우, 다음의 선택지들 중 하나를 골라잡을 것이다.
복사를 금지한다
실제로, 복사하면 안되는 RAII 클래스의 경우, 복사가 되지 않도록 막아야 한다. 예시는 다음과 같다. (항목 6 참고)
// 복사를 금지한다
class Lock: private UnCopyable
{
...
}
관리하고 있는 자원에 대해 참조 카운팅을 수행한다
shared_ptr 처럼 위의 Lock 클래스를 활용하면 어떨까? mutexPtr를 shared_ptr 로 선언하는 것이다! 다만, 참조하고 있는 포인터가 없을 때는 뮤텍스를 삭제하는 것이 아니라, 잠금 해제만 하도록 만들고 싶다. unique_ptr 는 해당 기능이 지원되지 않지만, shared_ptr 에서는 생성자의 두 번째 매개변수를 넣어 '삭제자' 함수를 지정해 줄 수 있다.
class Lock
{
public:
// 초기화 시, 삭제자로 unlock 함수를 사용한다
explicit Lock(Mutex *pm)
: mutexPtr(pm, unlock)
{
lock(mutexPtr.get());
}
private:
// 원시 포인터 대신 shared_ptr 을 사용한다
std::shared_ptr<Mutex> mutexPtr;
}
위의 코드에서는 소멸자 선언이 되어 있지 않은데, 그 이유는 Lock 에서 지정한 것처럼, mutexPtr 의 참조 카운트가 0이 될 때 삭제자(여기서는 unlock 함수) 가 호출될 것이기 때문이다.
관리하고 있는 자원을 진짜로 복사한다
'깊은 복사(deep copy)' 를 수행한다
관리하고 있는 자원의 소유권을 옮긴다
unique_ptr 처럼 std::move 를 사용해 소유권을 완전히 이전한다.
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective C++ | 항목 16 : new 및 delete 를 사용할 때는 형태를 반드시 맞추자 (0) | 2022.10.25 |
---|---|
Effective C++ | 항목 15 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자 (0) | 2022.10.25 |
Effective C++ | 항목 13 : 자원 관리에는 객체가 그만! (0) | 2022.10.25 |
Effective C++ | 항목 12 : 객체의 모든 부분을 빠짐없이 복사하자 (0) | 2022.10.25 |
Effective C++ | 항목 11 : operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자 (0) | 2022.10.25 |
Comments