unique_ptr은 이름에서부터 알 수 있듯이 한 인스턴스에 대한 소유권을 단 하나의 포인터에만 허락하는 스마트 포인터이다. 따라서 포인터간의 복사는 불가능하며, 이동은 가능하지만 std::move라는 함수를 이용해야만 가능하다.


저번에 사용한 것과 같이 다음과 같은 클래스가 있다고 가정해 보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyClass
{
public:
    int num;
    MyClass()
    {
        std::cout << "Ctor" << std::endl;
    }
 
    ~MyClass()
    {
        std::cout << "Dtor" << std::endl;
    }
};
cs


 int형 변수와 생성자, 소멸자에 출력문을 하나씩 갖고 있는 심플한 클래스이다.

이를 다음과 같이 unique_ptr을 이용해 main에서 생성, 출력을 하면 알아서 메모리를 해제해 준다.


1
2
3
4
5
6
7
8
int _tmain(int argc, _TCHAR* argv[])
{
    std::unique_ptr<MyClass> myClass(new MyClass);
    myClass->num = 1234;
    std::cout << myClass->num << std::endl;
    return 0;
}
 
cs




unique_ptr을 복사하려고 하면 컴파일 시점에 이렇게 에러가 발생한다.


error C2280: 'std::unique_ptr<MyClass,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': 삭제된 함수를 참조하려고 합니다.


한 인스턴스를 두개 이상의 포인터가 가리키는것은 불가능하므로 이동만 가능한데, 다음과 같은 방식으로 이동이 가능하다.


1
2
3
4
5
6
7
8
9
int _tmain(int argc, _TCHAR* argv[])
{
    std::unique_ptr<MyClass> myClass(new MyClass);
    std::unique_ptr<MyClass> myClass2 = std::move(myClass);
    myClass2->num = 1234;
    std::cout << myClass2->num << std::endl;
    return 0;
}
 
cs


std::move 이후 myClass는 NULL로 초기화되며 myClass2에 해당 인스턴스의 주소가 할당된다.




 weak_ptr은 shared_ptr의 단점을 보완하는 데에 사용되는 포인터이다.

shared_ptr의 경우 순환 참조(Circular references)라는 문제가 발생할 수 있다.

이는 shared_ptr가 서로를 참조하여 둘 모두 반환이 되지 않는 상태로, 일종의 메모리 데드락이라고 볼 수 있다.


 shared_ptr은 내부적으로 레퍼런스 카운팅을 통해 해당 인스턴스를 가리키는 포인터의 개수를 세지만, 사실 이 레퍼런스 카운트 변수는 두 가지의 종류가 있다. 이중 strong_count는 shared_ptr에서 메모리의 해제에 직접적으로 관여하는 카운트로, 0이 되면 메모리가 자동으로 해제된다. weak_count는 간단하게 같은 인스턴스를 가리키는 weak_ptr의 개수로, 이는 메모리의 해제에 영향을 미치지 않는다.


 weak_ptr은 기본적으로 shared_ptr과 같은 주소를 가리키지만 객체에 직접적인 참조는 불가능하다. 참조를 위해서는 lock() 함수를 이용해 shared_ptr을 반환받은 후 사용해야 한다. 만약 weak_ptr이 남아 있는 상태에서 shared_ptr이 전부 사라지면 메모리는 해제되고 lock() 함수에서는 nullptr이 반환된다. 그 반대로 weak_ptr이 전부 사라진다고 해도 shared_ptr이 남아 있다면 메모리는 해제되지 않는다.

shared_ptr의 참조자와 비슷한 역할을 하는 것이다.


http://blog.naver.com/wlstn3273/220713667682


 좋은 예시가 여기에 있으므로 여길 보고 따라가 보면 개념이 제대로 잡힐 것이라고 생각한다.

블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,