[Effective C++] #13 자원 관리 객체, std::auto_ptr, std::shared_ptr
Scott Meyers의 "Effective C++"를 통해, C++ 구현에 필요한 개념들을 이해하고, 기록하기 위함입니다. 해당 항목은 3장 "자원 관리", 항목 13 "자원 관리에는 객체가 그만"에 해당하는 내용입니다.
std::auto_ptr<Typename T>
A_클래스* createAClass(); // A클래스 객체를 가리키는 포인터를 반환, 팩토리 함수.
void f() {
A_클래스* pA = createAClass(); // 팩토리 함수 호출
...
delete pA; // pA 객체의 자원을 해제합니다.
}
*******************std::auto_ptr을 적용*******************
std::auto_ptr<A_클래스> createAClass(); // std:auto_ptr 객체를 반환
void f() {
std::auto_ptr <A_클래스> pA = createAClass(); // 팩토리 함수 호출
...
... // delete가 필요 없습니다.
}
"auto_ptr"은 스마트 포인터로, 가리키고 있는 대상에 대해 소멸자가 자동으로 delete를 호출합니다. 따라서, 팩토리 함수 호출로 생성한 새로운 객체의 자원 해제를 걱정하지 않아도 됩니다. "delete"를 사용해서 직접 자원을 해제할 경우, 이전의 소스 코드에서 예외가 던져지면, 자원이 정상적으로 해제되지 않는 문제가 발생할 수 있습니다. 상당수의 자원이 힙에서 동적으로 할당되고, 하나의 불록 혹은 함수 안에서만 쓰이는 경우가 많아서, 함수로부터 실행 제어가 빠져나올 때 자원이 해제되는 게 정상입니다. 이때, 사용하는 스마트 포인터가 "std::auto_ptr"입니다.
예제
std::auto_ptr<A_클래스> pA (createAClass ());
std::auto_ptr<A_클래스> pA2 (pA); // pA2는 pA가 가리키던 객체를 가리킵니다.
//이때, pA는 null이 됩니다.
pA = pA2; // pA2는 pA가 가리키던 객체를 가리킵니다.
//이때, pA는 null이 됩니다.
auto_ptr 객체는 가리키고 있는 대상에 대해 자동으로 delete를 호출하기 때문에, 한 객체를 두 개 이상의 auto_ptr가 존재하면 문제가 생깁니다. 이를 방지하기 위해 auto_ptr객체는 복사되면, 원본 객체는 null이 됩니다.
std::shared_ptr<Typename T>
shared_ptr은 복사 동작이 이뤄지는 환경에서 auto_ptr을 대체하기에 적합합니다. shared_ptr은 참조 카운팅 방식의 스마트 포인터로 어떤 객체를 참조하는 객체의 개수를 유지하고 있다가, 개수가 0이 되는 순간 해당 자원을 자동으로 삭제합니다.
예제
void someFunc() {
std::tr1::shared_ptr<A_클래스> pA (createAClass());
std::tr1::shared_ptr<A_클래스> pA2 (pA); // 참조 카운트가 증가합니다.
pA = pA2; // 아무런 변화가 없습니다.
... // 참조 카운팅이 0이되어 자원이 해제 됩니다.
}
복사 동작을 통해 증가하는 참조 객체의 객수를 유지하고, 함수 본문이 끝나면 자원을 자동으로 해제합니다. 주의할 점은 동적으로 할당한 배열에 대해 auto_ptr 혹은 shared_ptr을 사용하면 안 됩니다. 이들이 호출하는 것은 delete []가 아니기 때문입니다.
'언어 > Effective C++' 카테고리의 다른 글
[Effective C++] #15 자원 관리 객체, 자원에 대한 접근 (0) | 2022.01.15 |
---|---|
[Effective C++] #14 자원 관리 객체 심화, RAII, shared_ptr, 삭제자 지정 (0) | 2022.01.14 |
[Effective C++] #11 중복 참조와 자기 대입 연산자 (0) | 2022.01.12 |
[Effective C++] #10 대입 연산자와 *this의 참조자 (0) | 2022.01.12 |
[Effective C++] #9 가상 함수를 호출하는 생성자, 소멸자 (0) | 2022.01.10 |