본문으로 건너뛰기
모던 C++LESSON 18

스마트 포인터 입문: unique_ptr를 우선 고려하는 이유

난이도초급 → 중급 입문
예상 시간45분
선수지식이전 강의

18강. 스마트 포인터 입문: unique_ptr를 우선 고려하는 이유

이번 강의에서 해결할 문제​

new로 만든 객체를 raw pointer에 보관하면 누가 delete해야 하는지 타입에 표시되지 않습니다. 여러 반환 경로에서 삭제가 빠지거나 두 코드가 모두 소유자라고 생각해 이중 해제할 수 있습니다.

학습 목표​

  • unique_ptr가 동적 객체를 단독 소유함을 설명합니다.
  • make_unique로 객체를 만들고 자동 정리를 확인합니다.
  • 복사 대신 이동으로 소유권을 전달합니다.

먼저 알아야 할 핵심 개념​

std::unique_ptr<T>는 T 객체의 단일 소유자입니다. 복사할 수 없고 이동할 수 있습니다. 소유 포인터가 파괴되면 보유 객체도 자동 삭제됩니다. 공유가 요구사항으로 증명되지 않았다면 가장 단순한 값 객체 또는 unique_ptr부터 고려합니다.

가장 작은 실행 가능한 예제​

unique_inventory.cpp
#include <iostream>
#include <memory>
#include <utility>
#include <vector>

class Inventory {
public:
void add(const int itemId) { itemIds_.push_back(itemId); }
std::size_t size() const { return itemIds_.size(); }

private:
std::vector<int> itemIds_;
};

int main() {
auto inventory = std::make_unique<Inventory>();
inventory->add(10);
inventory->add(20);

auto ownedInventory = std::move(inventory);
std::cout << ownedInventory->size() << ' '
<< std::boolalpha << (inventory == nullptr) << '\n';
}

핵심 코드 줄별 설명​

  1. make_unique가 객체 생성과 소유 포인터 구성을 한 표현으로 처리합니다.
  2. ->로 소유 객체의 멤버를 호출합니다.
  3. std::move는 소유권 이전이 가능한 값으로 변환합니다.
  4. 이동 뒤 새 포인터가 객체를 소유합니다.
  5. 원래 inventory는 빈 상태이며 역참조하면 안 됩니다.

실행 결과와 값 변화​

2 true

ownedInventory가 범위를 벗어나면 Inventory가 자동 삭제됩니다. 이동 뒤 원래 포인터에 새 객체를 다시 대입하는 것도 가능합니다.

단계별 실습​

실습 목표​

단일 플레이어가 소유하는 장비 객체를 안전하게 생성·이동합니다.

시작 전 상태와 실행 방법​

이름을 가진 Equipment 클래스를 만들고 C++17 프로젝트에 <memory>를 포함합니다.

1단계: 최소 코드 작성​

make_unique<Equipment>로 검을 만들고 이름을 출력합니다.

2단계: 값 또는 조건을 바꿔 결과 비교​

다른 unique_ptr로 이동한 뒤 원본이 null인지 확인합니다.

3단계: 작은 기능 확장​

unique_ptr<Equipment>를 받아 소유권을 플레이어에게 전달하는 함수를 작성합니다.

4단계: 스스로 해결하기​

동적 할당 없이 값 멤버로 보관할 수 있다면 어느 쪽이 더 단순한지 비교하고 불필요한 포인터를 제거하세요.

막혔을 때​

복사 생성자가 삭제되었다는 오류는 단일 소유권을 복사하려 했다는 뜻입니다. 정말 소유권을 넘길 때만 std::move를 사용하고, 관찰만 필요하면 참조나 raw pointer를 짧게 전달합니다.

흔한 실수와 해결 방법​

  • 모든 객체를 unique_ptr로 만듦: 동적 수명이나 다형성 필요가 없으면 값이 더 단순합니다.
  • 이동 후 역참조: 원본은 null일 수 있으므로 새 소유자만 사용합니다.
  • get() 결과를 별도 소유자로 취급: 반환 raw pointer는 관찰자이며 delete하지 않습니다.

게임 개발 연결​

표준 C++ 게임 도구의 전략 객체나 선택적 하위 시스템을 단독 소유할 때 적합합니다. Unreal의 UObject는 GC 수명 규칙을 따르므로 std::unique_ptr<UObject>로 소유하지 않으며, 일반 C++ 타입에는 TUniquePtr 또는 프로젝트 규칙을 확인합니다.

이해 점검 질문 3개​

  1. unique_ptr를 복사할 수 없는 이유는 무엇인가요?
  2. 이동 뒤 원래 포인터는 어떻게 다뤄야 하나요?
  3. 값 멤버가 unique_ptr보다 더 좋은 선택일 수 있는 경우는 언제인가요?

핵심 요약​

unique_ptr는 동적 객체의 삭제 책임을 한 소유자에 고정합니다. 값으로 충분한지 먼저 확인하고, 동적 단일 소유가 필요할 때 make_unique와 이동을 사용합니다.

다음 강의 연결​

19강. 값·참조·포인터 기준에서 소유가 아닌 함수 호출 관계를 가장 단순한 인자 타입으로 표현합니다.

MINI QUIZ

스마트 포인터 입문: unique_ptr를 우선 고려하는 이유 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“스마트 포인터 입문: unique_ptr를 우선 고려하는 이유”의 역할과 의존성을 판단하는 올바른 기준은 무엇인가요?
  2. 문제 2“스마트 포인터 입문: unique_ptr를 우선 고려하는 이유”의 작업 기준으로 ‘get() 결과를 별도 소유자로 취급’을 진단하거나 바로잡은 선택은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

18강. 스마트 포인터 입문: unique_ptr를 우선 고려하는 이유 미완료 상태