Post
자원을 객체에 넣음으로써, C++가 자동으로 호출해 주는 소멸자에 의해 해당 자원을 저절로 해제할 수 있다.
표준라이브러리에 auto_ptr클래스가 있는데, 이 클래스는 포인터와 비슷하게 동작하는 스마트포인터로서 가리키고있는 대상에 대해 소멸자가 자동으로 delete를 불러주도록 설계되어있다.
void f()
{
Investment *pInv(createInvestment());
//createInvestment() 는 Investment 클래스의 객체를 동적할당하고 포인터 반환함수
...
delete pInv;
}
void f()
{
std::auto_ptr<Investment>pInv(createInvestment());
...
}
위의 코드에서는 delete에 도달하기전에 빠져나갈 요소들이 분명 많아보이지만, 밑에 auto_ptr을 쓰는 경우에는 위의 코드에서 생길 수 있는 자원누출을 막을 수 있다.
여기서, 자원관리에 객체를 사용하는 방법의 두가지 특징을 알 수 있다.
1. 자원을 획득한 후에 자원 관리 객체에게 넘긴다.
자원획득 초기화( Resource Acquisition Is Initialization: RAII) 라는 용어가 있다. 자원획득과 자원관리 객체의 초기화가 한문장에서 이루어진다는것이다.
2. 자원관리 객체는 자신의 소멸자를 사용해서 자원이 확실히 해제되도록 한다.
auto_ptr은 자신이 소멸될때 가리키고 있는 대상에 대해서도 자동으로 delete를 해준다.
그렇기때문에 객체를 가리키는 auto_ptr이 둘이상이라면 자원이 두번 이상 삭제되는 결과가 나온다.
이러한 상황을 막기위해 auto_ptr객체를 복사하면 원본 객체는 null로 만든다.
하지만 auto_ptr을 쓰지 못하는 상황(STL 컨테이너)이라면 참조카운팅 방식 스마트 포인터(reference-counting smart pointer: RCSP)방식 또한 좋다.
가비지 컬렉션과 비슷하게 어떤 자원을 가리키는 외부 객체의 개수를 유지하고있다가 그 개수가 0이 되면 해당 자원을 자동으로 삭제하는 스마트포인터인데, 가비지 컬렉션과 다르게 서로가리키고 있는 상황에서도 없앨 수 있단게 특징이다.
void f()
{
std::tr1::shared_ptr<Investment>pInv(createInvestment());
// tr1::shared_ptr이 대표적인 RCSP이다.
...
}
하지만 여기서 중요하게 봐야할건, auto_ptr, shared_ptr 둘다 동적으로 할당한 배열에 대해서는 쓰지 못한다.
왜냐하면 동적으로 할당도니 배열은 vector나 string으로 대체할 수 있기때문이다.
'STUDY > Effective C++' 카테고리의 다른 글
항목 14: 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자 (0) | 2022.10.28 |
---|---|
항목 12: 객체의 모든 부분을 빠짐없이 복사하자 (0) | 2022.09.08 |
항목 11: operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자 (0) | 2022.08.31 |
항목 10 : 대입 연산자는 *this의 참조자를 반환하게 하자 (0) | 2022.08.24 |
항목 9 : 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자 (0) | 2022.08.17 |