방법: unique_ptr 인스턴스 만들기 및 사용
unique_ptr 포인터를 공유하지 않습니다. 다른 unique_ptr
함수로 복사하거나, 값으로 함수에 전달하거나, 복사본을 만들어야 하는 C++ 표준 라이브러리 알고리즘에서 사용할 수 없습니다. unique_ptr
은 이동만 할 수 있습니다. 즉, 메모리 리소스의 소유권이 다른 unique_ptr
로 이전되어 원래 unique_ptr
이 더 이상 소유하지 않습니다. 소유권이 여러 개이면 프로그램 논리가 복잡해지기 때문에 개체를 하나의 소유자로 제한하는 것이 좋습니다. 따라서 일반 C++ 개체에 대한 스마트 포인터가 필요한 경우 해당 개체를 사용하고 unique_ptr
생성unique_ptr
할 때 make_unique 도우미 함수를 사용합니다.
다음 다이어그램은 두 unique_ptr
인스턴스 사이의 소유권 이전을 보여 줍니다.
unique_ptr
는 C++ 표준 라이브러리의 <memory>
헤더에 정의됩니다. 원시 포인터만큼 효율적이며 C++ 표준 라이브러리 컨테이너에서 사용할 수 있습니다. C++ 표준 라이브러리 컨테이너에 인스턴스를 추가 unique_ptr
하면 복사 작업이 필요하지 않으므로 이동 생성자가 unique_ptr
효율적입니다.
예 1
다음 예제에서는 unique_ptr
인스턴스를 어떻게 만들고 이를 함수 사이에서 어떻게 전달하는지를 보여 줍니다.
unique_ptr<Song> SongFactory(const std::wstring& artist, const std::wstring& title)
{
// Implicit move operation into the variable that stores the result.
return make_unique<Song>(artist, title);
}
void MakeSongs()
{
// Create a new unique_ptr with a new object.
auto song = make_unique<Song>(L"Mr. Children", L"Namonaki Uta");
// Use the unique_ptr.
vector<wstring> titles = { song->title };
// Move raw pointer from one unique_ptr to another.
unique_ptr<Song> song2 = std::move(song);
// Obtain unique_ptr from function that returns by value.
auto song3 = SongFactory(L"Michael Jackson", L"Beat It");
}
이러한 예는 unique_ptr
의 기본적인 특징을 보여 주며 이동은 가능하지만 복사되지 않을 수 있습니다. "이동"이 소유권을 새 unique_ptr
로 이전하고 이전 unique_ptr
을 다시 설정합니다.
예제 2
다음 예제에서는 unique_ptr
인스턴스를 만들고 이를 벡터에 사용하는 방법을 보여 줍니다.
void SongVector()
{
vector<unique_ptr<Song>> songs;
// Create a few new unique_ptr<Song> instances
// and add them to vector using implicit move semantics.
songs.push_back(make_unique<Song>(L"B'z", L"Juice"));
songs.push_back(make_unique<Song>(L"Namie Amuro", L"Funky Town"));
songs.push_back(make_unique<Song>(L"Kome Kome Club", L"Kimi ga Iru Dake de"));
songs.push_back(make_unique<Song>(L"Ayumi Hamasaki", L"Poker Face"));
// Pass by const reference when possible to avoid copying.
for (const auto& song : songs)
{
wcout << L"Artist: " << song->artist << L" Title: " << song->title << endl;
}
}
루프 범위에서 unique_ptr
이 참조로 전달됩니다. 여기에서 값으로 전달하려는 경우 unique_ptr
복사 생성자가 삭제되기 때문에 컴파일러는 오류를 throw합니다.
예 3
다음 예제에서는 클래스 멤버인 unique_ptr
을 초기화하는 방법을 보여 줍니다.
class MyClass
{
private:
// MyClass owns the unique_ptr.
unique_ptr<ClassFactory> factory;
public:
// Initialize by using make_unique with ClassFactory default constructor.
MyClass() : factory (make_unique<ClassFactory>())
{
}
void MakeClass()
{
factory->DoSomething();
}
};
예제 4
make_unique 사용하여 배열을 만들 unique_ptr
수 있지만 배열 요소를 초기화하는 데는 사용할 make_unique
수 없습니다.
// Create a unique_ptr to an array of 5 integers.
auto p = make_unique<int[]>(5);
// Initialize the array.
for (int i = 0; i < 5; ++i)
{
p[i] = i;
wcout << p[i] << endl;
}
자세한 예제는 make_unique 참조하세요.
참고 항목
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기