프로그래밍/C/C++

[C++] 스마트포인터 unique_ptr [정보공유의 장]

nanze 2022. 1. 16. 21:19
반응형

C++ 스마트 포인터(Smart pointer) unique_ptr

이번 포스팅 정리는 스마트 포인터 중 unique_ptr 에 대해서 정리해 보자. 

unique_ptr 은 소유하는 포인터에 대해 다음과 같은 규칙을 갖는다. 

1. 소유 포인터는 한 개의 객체만이 소유할 수 있다. 

2. 원래 포인터의 소유권을 이동시키는 것은 가능하지만 복사나 대입은 불가능하다.

3. unique_ptr 객체가 소멸될 때 소유 포인터의 메모리도 해제된다. 

우선 unique_ptr 을 생성하는 문법적인 요소를 알아보도록 하자.

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    unique_ptr<int> p1(new int(2));
    unique_ptr<int> p2 = make_unique<int>(2);
    return 0;
}

unique_ptr 을 생성하기 위해서는 위 코드와 같이 인자를 이용하는 생성자 방식과 make_unique 함수를 이용한  방식이 존재한다. unique_ptr 객체는 선언된 영역을 벗어나면 소멸자가 호출되게 되고 소멸자 내에서는 소유 포인터에 대한 메모리를 해제한다. 

만약 배열을 위한 unique_ptr 객체를 생성하기 위해서는 다음과 같은 코드를 작성해야 한다. 

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    unique_ptr<int> p1 = make_unique<int[]>(100);
    return 0;
}

위 코드는 int 배열 크기 100을 가리키는 unique_ptr 을 생성한 것이다. 

unique_ptr 또한 shared_ptr 과 같이 get() 함수를 통해서 소유 포인터를 반환할 수 있다. 하지만 소유권 자체를 놓은 것은 아니기에 사용에 있어서 주의가 필요하다. 

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    unique_ptr<int> p1(new int(2));
    int* p2 = p1.get();
    return 0;
}

 

unique_ptr 은 reset() 함수를 이용하여 현재 소유 중인 포인터를 삭제 또는 다른 포인터로 설정할 수 있다. reset() 함수 내에 인자가 있을 경우에는 해당 포인터로 변경되면 기존 포인터는 삭제된다. 인자가 없을 경우에는 현재 가지고 있는 포인터의 메모리를 해제한다. 

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    unique_ptr<int> p1(new int(2));
    unique_ptr<int> p2 = make_unique<int>(2);
    p1.reset();
    p2.reset(new int(5));
    return 0;
}

unique_ptr 은 release() 함수를 이용하여 소유 포인터를 메모리 해제하지 않고 외부로 반환할 수 있다. 하지만 주의할 것은 unique_ptr 의 소유권은 해제되었기 때문에 해당 포인터에 대한 메모리는 프로그램 내에서 잘 관리되어야 한다. 

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    unique_ptr<int> p1(new int(2));
    int* p2 = p1.release();
    //p2 메모리는 수동으로 메모리가 해제되어야 한다.
    return 0;
}

unique_ptr 은 shared_ptr 과 마찬가지로 소유 포인터를 다른 unique_ptr로 이동시킬 수 있다. 이동시키기 위한 함수는 당연히 마찬가지로 std::move() 이다. 해당 함수는 알다싶이 rvalue reference 강제 형변환시키는 것으로 move() 함수 이용하여 대입 시 이동 대입 연산자 또는 이동 복사 생성자가 호출 됨으로써 이동이 가능하다. 

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    unique_ptr<int> p1(new int(2));
    //unique_ptr<int> p2 = p1  이 경우는 에러가 발생한다.
    unique_ptr<int> p2 = move(p1);
    
    return 0;
}

이것으로 스마트 포인터 중 unique_ptr 에 대해서 정리해보았다. 

관련 이전 포스팅

2022.01.15 - [프로그래밍/C/C++] - [C++] 스마트포인터 shared_ptr - 정보공유의 장

 

[C++] 스마트포인터 shared_ptr - 정보공유의 장

이번 포스팅은 스마트 포인터 중 shared_ptr 에 대해서 정리해보겠다. shared_ptr in C++ 11 shared_ptr 은 c++ 11 이후 제공되는 스마트 포인터 중 하나로 포인터를 더 이상 사용하지 않을 경우 메모리를 자동

nanze.tistory.com

 

반응형