Post List

2015년 4월 10일 금요일

Chapter 4. 스마트 포인터 (Smart Pointer)

작가
Meyers, Scott
출판
O'ReillyMedia
발매
2014.12.12
평점








Effective Modern C++ - Scott Meyers
Chapter 4. Smart Pointer


그 동안은 챕터의 머릿말에 대해서는 특별히 언급없이 바로 각 item에 대해서 다루었는데,
스마트 포인터의 경우 머릿말에도 알아두면 좋을 내용이 있어서 짧게 언급하고 넘어가겠습니다.

"C/C++에서 빠질수 없는 가장 강려크한 도구는 포인터(Pointer)다."
라는 말에 반대의견을 던질 분은 많지 않을 겁니다.

포인터 (또는 레퍼런스) 를 사용하지 않고, C/C++의 코드를 짜면 기능적으로든, 성능적으로든 큰 제약을 받게 됩니다.


하지만, Raw Pointer를 마음놓고 편하게 사용하기에는 다음과 같은 어려움들이 있습니다.

1. 싱글 오브젝트인지 배열인지 알 수가 없습니다.

2. 해당 포인터를 사용한 후에 해제를 해야 하는지 여부를 알 수 없습니다.
   다른 곳에서 또 다시 사용을 한다면 해제를 하면 안됩니다.
   반대로, 다른 곳에서 사용하는 곳이 없는데 해제를 안한다면 메모리 누수 (memory leak)을 발생 시킵니다.

3. 포인터가 가리키는 것을 해제하려 할때 그 방법을 알 수 없습니다.
    delete로 할지, 아니면 다른 방법으로 해야 할지...

4. delete로 해제 하려 할때도 싱글 오브젝트 (delete) 와 배열 (delete []) 에 따라 다르게 해야 하는데도,
   둘 중 어떤 것을 실행해도 다 수행됩니다. 물론 잘못 해제를 하면, 문제가 생깁니다.

5. 정확히 해제 방법을 알았더라도, 해제 작업이 딱 한 번만 이루어 져야하는데,
   그전에 다른 곳에서 해제시켰는지 유무를 알 수 없습니다.

6. Dangling 포인터(이미 해제된 개체를 가리키는 포인터) 인지 여부를 알 수 없습니다.


Raw Pointer 는 C++에서 사용하지 않을 수 없을 만큼 매우 강력한 도구 입니다.
하지만 사용하기가 쉽지 않으며, 잘못 사용할 경우 디버깅하는데 애를 먹습니다.

여기에 대한 해답으로 스마트 포인터(Smart Pointer)가 있습니다.
스마트 포인터는 Raw Pointer와 거의 비슷하게 동작하면서도, 위에 나열한 단점들을 많이 해결하였습니다.


C++11에는 4개의 스마트 포인터가 있습니다.

그것들은 모두 개체 생성을 동적으로 하면서, 누수를 방지하고, 적절한 때에 해제 될수 있도록 해주는 기능을 제공합니다.

1. std::auto_ptr

C++98에서도 별로 쓰이지 않았습니다.
COPY가 되지않고 MOVE 되어야 하는데도 불구하고 C++98에는 적절한 Move semantics가 없었습니다.
그래서 어쩔수 없이 COPY를 이용하면서, 이런 저런 문제들이 있었습니다.
C++11에서 또한 잘 사용되지 않고, 대신 std::unique_ptr을 사용합니다.

2. std::unique_ptr

개체를 공유하지 않고, 유일한 소유권으로 관리하기 위한 스마트 포인터입니다.
모든 면에서 std::auto_ptr보다 더 좋습니다.

3. std::shared_ptr

개체를 여러군데서 공유하면서, 아무도 사용하지 않을 때 자원을 해제하도록 하는 기능을 제공하는 스마트 포인터 입니다.

4. std::weak_ptr

std::shared_ptr의 순환 참조를 방지하고, dangling pointer 여부 확인을 위해서 사용하는 스마트 포인터 입니다.


위에 언급한 스마트 포인터 중 std::auto_ptr을 제외하고 나머지 3가지에 대해서 앞으로 알아보도록 하겠습니다.