Post

[ STUDY/Effective C++ ] 2022. 9. 22. 12:40

자원을 객체에 넣음으로써,  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으로 대체할 수 있기때문이다.

 

 

▲ top