2018년 5월 21일 월요일

C++ 11/14 관련 내용 대충 정리, 스마트 포인터

최신 C++을 공부하려 책을 보긴 했었는데
내용이 기존 문법과 함께 여기저기 흩어져 있어 보기에 좀 어려워
MSDN을 참고하여 대충 정리하려함.


C++11/14/17 기능에 대한 지원(최신 C++)
https://msdn.microsoft.com/ko-kr/library/hh567368.aspx


스마트 포인터

: https://msdn.microsoft.com/ko-kr/library/hh438480.aspx


- <memory>  헤더의 std 네임스페이스에 정의
- RAII (Resource Acquisition Is Initialialization) 위해 사용 가능
 : RAII의 기본 원칙은 힙 할당 리소스(예: 동적 할당 메모리 또는 시스템 개체 핸들)의 소유권을 해당 소멸자가 리소스를 삭제, 정리하는 코드를 가진 스택 할당 개체를 제공
- 생성한 개체를 스마트 포인터로 즉시 전달하는 것을 추천.
- 소유권 혼동 여지가 없는 제한된 범위, 루프 또는 지원 함수의 작은 코드 블록에서만 사용


void UseRawPointer()
{
    // Using a raw pointer -- not recommended.
    Song* pSong = new Song(L"Nothing on You", L"Bruno Mars"); 

    // Use pSong...

    // Don't forget to delete!
    delete pSong;   
}


void UseSmartPointer()
{
    // Declare a smart pointer on stack and pass it the raw pointer.
    unique_ptr<Song> song2(new Song(L"Nothing on You", L"Bruno Mars"));

    // Use song2...
    wstring s = song2->duration_;
    //...

} // song2 is deleted automatically here.


class LargeObject
{
public:
    void DoSomething(){}
};

void ProcessLargeObject(const LargeObject& lo){}
void SmartPointerDemo()
{    
    // Create the object and pass it to a smart pointer
    std::unique_ptr<LargeObject> pLarge(new LargeObject());

    //Call a method on the object
    pLarge->DoSomething();

    // Pass a reference to a method.
    ProcessLargeObject(*pLarge);

} //pLarge is deleted automatically when function block goes out of scope.


스마트 포인터를 사용하는 필수 단계
  1. 스마트 포인터를 자동(지역) 변수로 선언합니다. (스마트 포인터 자체에 new 또는 malloc 식을 사용하지 마십시오.)
  2. 형식 매개 변수에서 캡슐화된 포인터가 가리키는 대상의 형식을 지정합니다.
  3. 원시 포인터를 스마트 포인터 생성자의 new-ed 개체에 전달합니다. (일부 유틸리티 기능 또는 스마트 포인터 생성자로 이 작업을 자동으로 수행할 수 있습니다.)
  4. 오버로드된 -> 및 * 연산자를 사용하여 개체에 액세스합니다.
  5. 스마트 포인터가 소멸 될 때 개체가 함께 삭제됨.

void SmartPointerDemo2()
{
    // Create the object and pass it to a smart pointer
    std::unique_ptr<LargeObject> pLarge(new LargeObject());

    //Call a method on the object
    pLarge->DoSomething();

    // Free the memory before we exit function block.
    pLarge.reset();

    // Do some other work...

}

. -> 로는 스마트 포인터가 가진 개체를 참조하고 .은 스마트 포인터의 멤버함수를 참조한다.
. .get()으로 원시 포인터를 전달 할 수 있음. (언제 필요할까?)


스마트 포인터의 종류


C++ 표준 라이브러리 스마트 포인터
. POCO(Plain Old C++ Object)에 대한 포인터를 캡슐화 하는 데 가장 먼저 스마트 포인터를 사용함.

. unique_ptr
 : 한 명의 소유자만 허용함, 새 소유자로 이동할 수 있지만 복사 불가.
 : 작고 효율적이며 크기는 1 포인터
 : STL 컬렉션에서 빠른 삽입 및 검색을 위해 rvalue 참조 지원

. shared_ptr
 : 참조 횟수가 계산되는 스마트 포인터, 하나의 원시 포인터 하나를 여러 소유자에게 할당 하려고 할 경우(컨테이너에서 포인터 복사본을 반환 시 원본을 유지하고 싶을 때)
 : 원시포인터는 모든 소유자가 없어지기 전까지 삭제되지 않는다.
 : 크기는 2 포인터, 하나는 개체용, 다른 하나는 참조 횟수를 위해

. weak_ptr
 : shared_ptr 와 함께 사용할 수 있는 스마트 포인터
 : shared_ptr의 개체를 weak_ptr로 참조해도 shared_ptr의 참조 카운트가 증가하지 않음.
 : 개체가 삭제 되지 않게 되는 상황인 shared_ptr의 상호 참조를 차단하기 위해 사용


댓글 없음:

댓글 쓰기