SW/C++

C++ : unique_ptr : reset, get, release, move, 복사 : 개념, 예제

얇은생각 2020. 5. 5. 07:30
반응형

C++ : unique_ptr : reset, get, release, move, 복사 : 개념, 예제

 

reset()

int main()
{
  std::unique_ptr<Vector> vector = std::make_unique<Vector>(10.f, 30.f);
  vector.reset(new Vector(20.f, 40.f));
  vector.reset();
}

 

이거 말고 nullptr를 써야할까?

vector.reset();

vecotr = nullptr;

두 코드의 의미는 같습니다. nullptr가 reset() 보다 가독성이 더 좋습니다. reset()은 vector가 원시 포인터가 아님을 분명하게 보여줍니다. 따라서, 취향에 맞게 구현하여도 무방하다고 합니다. reset()은 결국 포인터를 교체하는 것을 의미합니다. std::unique_ptr가 재설정 될 떄, 소유하고 있던 원시 포인터는 자동으로 소멸됩니다.

 

 

get()

Vector * ptr = vector.get();

원시 포인터를 반환합니다.

 

 

release()

Vector* vectorPtr = vector.release();

Vector* vectorPtr = vector.get(); // nullptr

원시 포인터에 대한 소유권을 박탈하고 원시 포인터를 반환합니다. releas() 호출 후 get()을 호출하면 nullptr가 반환됩니다.

 

 

유니크 포인터를 복사할 수 있나요?

안됩니다. 포인터 소유권을 다른 std::unique_ptr로 옮길 수 만 있습니다.

#include<memory>
#include"Vector.h"

int main()
{
  std::unique_ptr<Vecotr> vector = std::make_unique<Vecotr>(10.f, 30.f);
  std::unique_ptr<Vector> anotherVector(std::move(vecotr));
  
  // ...
}

 

 

const 유니크 포인터는 어떨까?

const std::unique_ptr<Vecotr> vector = std::make_unique<Vector>(10.f, 30.f);

const 유니크 포인터의 경우에는 소유권 이전이 되지 않고 컴파일 에러가 일어납니다.

std::unique_ptr은 소유한 원시 포인터를 아무하고도 공유하지 않습니다. 즉, 주소 복사를 하지 않는다는 뜻입니다. 대신, 소유권을 다른 std::unique_ptr로 옮길 수 있습니다. 예외인 const std::unique_ptr을 제외하고는 말입니다.

 

 

std::move()

개체 A의 모든 멤버를 포기하고 그 소유권을 B에게 주는 방법입니다. 메모리 할당과 해제가 일어나지 않습니다. A에 있는 모든 포인터를 B에게 대입하고 A에는 nullptr를 넣는다고 생각하면 좋습니다. 이게 어떻게 동작하는 지 이해하기 위해서는 r-value와 이동(move) 생성자를 이해해야 합니다.

 

 

STL 벡터에 요소 추가하기

std::vecotr<std::unique_ptr<player>> players;
std::unique_ptr<Player> coco = std::make_unique<Player>("COCO");
players.push_back(std::move(coco));

 

벡터안에 유니크 포인터를 추가하기 위해서는, move 함수를 활용해서, 소유권 전체를 넘겨주어야지만 컴파일이 정상적으로 동작합니다. 유니크포인터를 만들때는 make_unique를 잘활용해서 만들어 주어야 하는 것을 알 수 있습니다.

반응형