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를 잘활용해서 만들어 주어야 하는 것을 알 수 있습니다.
'SW > C++' 카테고리의 다른 글
C++ : 자동 메모리 관리, 가비지 컬렉션, 참조 카운트 : 개념, 관계, 장단점 (0) | 2020.05.07 |
---|---|
C++ : unique_ptr : 배스트 프렉티스, 기본 예제, 활용 방법, 동작 방식 (0) | 2020.05.06 |
C++ : unique_ptr : 유니크 포인터 개념, 필요성, 장점, 활용법 (0) | 2020.05.04 |
C++ : std::array : 개념, 장점, 단점, 필요성, 활용성, 예제, 구현 (0) | 2020.05.03 |
C++ : 범위 기반 for 반복문 : 장점, 개념, 예제, 구현 (0) | 2020.05.02 |