[C++] 항목 14: 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자

업데이트:     Updated:

카테고리:

태그:

이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 GPT에게 요약을 요청하여 작성되었습니다.
이펙티브 C++ 제3판, 스콧 마이어스 저자, 곽용재 번역

📦 3. 자원 관리

👉🏻 항목 14: 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자

자원은 꼭 힙에 만들 필요는 없다.
뮤텍스(Mutex) 처럼 C API로 관리하는 자원은 스마트 포인터보단 직접 관리 클래스를 만드는 게 낫다.

void lock(Mutex* pm);     // 잠금
void unlock(Mutex* pm);   // 해제



✅ RAII 스타일로 자원 관리

class Lock {
public:
	explicit Lock(Mutex *pm) : mutexPtr(pm) {
		lock(mutexPtr);
	}
	~Lock() {
		unlock(mutexPtr);
	}
private:
	Mutex *mutexPtr;
};
  • 생성 시 자원을 잠그고
  • 소멸 시 자원을 해제한다
    RAII 스타일로 예외에도 안전하게 동작한다.



❓ 복사를 시도하면?

Lock m11(&m);
Lock m12(m11); // 복사해도 되나?

RAII 객체는 자원에 따라 복사 허용 여부가 달라진다.



1️⃣ 복사 금지

뮤텍스처럼 동기화 자원은 복사하면 위험하다.
Uncopyable 상속 등으로 복사를 아예 막는 게 일반적이다. (항목 6 참고)



2️⃣ 참조 카운팅 (shared_ptr)

자원을 여러 객체가 공유해야 한다면, shared_ptr로 참조 카운팅하면서
삭제자만 잠금 해제 함수로 지정하면 된다.

shared_ptr<Mutex> ptr(pm, unlock);

→ 참조 카운트가 0이 될 때 unlock 호출
→ RAII에 따라 자동 해제됨 (항목 5 관련)



3️⃣ 깊은 복사

자원을 진짜로 복사해야 하는 상황이면
깊은 복사(deep copy)를 구현해서 각 객체가 자기 자원만 책임지도록 해야 한다.



4️⃣ 소유권 이전 (Move)

복사 대신 소유권 이전(move) 만 허용하고 싶다면
unique_ptr처럼 이동만 가능한 방식으로 구현하면 된다.
(예전엔 auto_ptr이 이런 방식)



🧐 정리

  • RAII 객체 복사 허용 여부는 관리 자원에 따라 다르다.
  • 일반적인 대응 방식:

    1. 복사 금지
    2. 참조 카운팅
  • 그 외 대응: 3. 깊은 복사 4. 소유권 이전

→ 상황에 따라 복사 가능성 여부와 방식 모두 신중히 결정해야 한다.

Cpp 카테고리 내 다른 글 보러가기

댓글남기기