std::unique_ptr
개요
std::unique_ptr
는 C++11부터 도입된 스마트 포인터로, 동적으로 할당된 객체에 대한 독점적인 소유권을 관리합니다. unique_ptr
가 소멸될 때 (예: 범위를 벗어날 때) 관리하던 객체도 자동으로 소멸시켜, 메모리 누수를 방지하고 예외 안전성을 높입니다. 복사가 불가능하고 이동만 가능하다는 특징이 있습니다.
C++ 버전별 주요 키워드 도입 시기
- C++11:
std::unique_ptr
도입 - C++14:
std::make_unique
헬퍼 함수 도입
내용 설명
std::unique_ptr
는 이름 그대로 포인터가 가리키는 객체에 대한 유일한(unique) 소유권을 가집니다. 이는 복사 생성자나 복사 대입 연산자가 없어 복사가 원천적으로 불가능하며, 소유권은 std::move
를 통해서만 이전될 수 있음을 의미합니다.
unique_ptr
의 가장 큰 장점은 범위 기반 리소스 관리(RAII, Resource Acquisition Is Initialization)를 단순화한다는 것입니다. unique_ptr
객체가 범위를 벗어나면 소멸자가 호출되고, 이 소멸자는 자신이 관리하던 객체를 자동으로 delete
해줍니다. 이로 인해 개발자가 delete
를 수동으로 호출할 필요가 없어지므로 메모리 누수 실수를 크게 줄일 수 있습니다.
C++14부터는 std::make_unique
함수를 사용하는 것이 권장됩니다. 이 함수는 코드를 더 간결하게 만들고, 예외 발생 시에도 메모리 누수가 발생하지 않도록 보장하여 예외 안전성을 높여줍니다.
예제 코드
#include <iostream>
#include <memory>
class ScopeTest
{
public:
ScopeTest(int val) : m_val(val)
{
std::cout << "Constructor: " << m_val << '\n';
}
~ScopeTest()
{
std::cout << "Destructor!\n";
}
void test()
{
std::cout << "Test!\n";
}
private:
int m_val;
};
// std::unique_ptr를 사용하여 자동 메모리 관리
void f1()
{
auto t = std::make_unique<ScopeTest>(10);
t->test();
} // t가 범위를 벗어나면서 ScopeTest 객체가 자동으로 소멸됨
// new/delete를 사용한 수동 메모리 관리
void f2()
{
// t2 포인터 변수는 stack에 생성되고, heap에는 ScopeTest 객체가 생성되고 t2 포인터가 가리킴
auto *t2 = new ScopeTest(10);
t2->test();
delete t2; // 수동으로 delete 호출 필요
}
int main()
{
f1();
std::cout << '\n';
f2();
return 0;
}
실행 결과
Constructor: 10
Test!
Destructor!
Constructor: 10
Test!
Destructor!
활용팁
std::make_unique
사용: C++14 이상 환경에서는new
를 직접 사용하는 대신std::make_unique
를 사용하세요. 코드가 간결해지고 예외 안전성이 향상됩니다.- 기본 스마트 포인터로 사용: 동적으로 할당된 객체를 관리할 때, 공유 소유권(
std::shared_ptr
)이 명확하게 필요하지 않은 이상std::unique_ptr
를 기본으로 사용하는 것이 좋습니다. - 소유권 이전: 함수에서 생성한 객체의 소유권을 호출자에게 넘겨줄 때
std::unique_ptr
를 반환 값으로 사용하면 편리합니다. - 레거시 API와 연동:
get()
멤버 함수를 사용하면 관리 중인 객체의 원시 포인터(raw pointer)를 얻을 수 있습니다. 단, 이 포인터를delete
해서는 안 됩니다. - 소유권 해제 및 재설정:
release()
는unique_ptr
의 소유권을 포기하고 원시 포인터를 반환하며,reset()
은 현재 관리하는 객체를 파괴하고 선택적으로 새로운 객체의 소유권을 가질 수 있게 합니다.
'개발 > C++ (98,03,11,14,17,20,23)' 카테고리의 다른 글
Modern C++ : std::format (20) (0) | 2025.10.12 |
---|---|
Modern C++ : std::ranges (20) (0) | 2025.10.11 |
Modern C++ : std::Attributes (11, 14, 17, 20) (0) | 2025.10.10 |
Modern C++ : std::any (17) (0) | 2025.09.30 |
Modern C++ : std::variant (17) (0) | 2025.09.29 |
Modern C++ : std::optional (17) (0) | 2025.09.28 |
Modern C++ : Type Traits 2 (11, 14, 17, 20) (0) | 2025.09.27 |
Modern C++ : Variadic Templates and Fold Expressions (11, 17) (0) | 2025.09.26 |