메모리 누수를 막는 코드를 짜면서, 여러가지 방식을 테스트 하다가 지금까지 써보지 않은 방식인 스마트 포인터를 사용해 보면서 정리해 보았다.
관련 코드는 아래 깃허브의 TEXT_RPG 폴더를 체크해 보면 된다.
https://github.com/GbLeem/Cpp_Issues
1. unique_ptr 간단한 문법
unique_ptr은 <memory> 헤더에 정의되어있으며, 단 하나의 소유권만 가지게 하는 smart pointer이다.
- unique_ptr<type> name;
- 위와 같은 모습으로 선언할 수 있다.
- 주의할 것은 대입과 복사는 불가능하고, 이동 연산은 가능하다.
unique_ptr<Test> uPtr1;
unique_ptr<Test> uPtr2(uPtr1); //복사 불가능
uPtr2 = uPtr2; //대입 불가능
unique_ptr<Test> uPtr3(move(uPtr1)); //가능
- make_unique<type>();
- C++14에서 도입된 함수
- unique_ptr을 생성할 때는 이 함수를 이용하는 것이 좋다.
2. 발생한 이슈들
1. 함수의 return 값
//Character.h
...
static unique_ptr<Character> GetInstance(string name);
//Character.cpp
...
unique_ptr<Character> Character::GetInstance(string name)
{
if (!instance)
{
instance = unique_ptr<Character>(new Character(name));
}
return instance;
}
//main.cpp
...
unique_ptr<Character> playerCharacter = move(Character::GetInstance(name));
- 위와 같이 GetInstance 함수를 구성하게 되면, 아래 사진의 오류가 발생한다. (리턴 값을 주의해서 보자)

- 그 이유는 unique_ptr은 복사와 대입이 불가능하기 때문이다.
- 우리가 return 값으로 그냥 unique_ptr을 주게 된다면, 그 값을 return 한다는 의미이기 때문에 GetInstance 함수를 통해서 값의 복사가 일어날 수 있게 된다. (좀 더 이해가 필요한 부분)
- 그렇기 때문에 아래 코드와 같이 &를 붙여서 참조로 return 값을 설정해주어야 한다.
- 이후 우리가 사용할 때는 위의 코드의 마지막 줄처럼
- move를 통해 GetInstance를 통해 받은 참조값을 playerCharacter 라는 unique_ptr로 이동시켜주어서 사용하면 된다.
//Character.h
...
static unique_ptr<Character>& GetInstance(string name);
//Character.cpp
...
unique_ptr<Character>& Character::GetInstance(string name)
{
if (!instance)
{
instance = unique_ptr<Character>(new Character(name));
}
return instance;
}
2. 함수의 매개변수
//Character.h
...
vector<unique_ptr<Item>> mItems;
//Character.cpp
...
void Character::AddItemToInventory(unique_ptr<Item> item)
{
mItems.push_back(item);
}
- 위와 같이 item을 push_back을 해서 넣어주려고 하면 아래와 같은 오류가 발생하게 된다.

- 그 이유는 마찬가지로 복사와 대입이 불가능한데, 복사를 하려고 해서 생기는 문제이다.
- unique_ptr은 복사를 할 수 없기 때문에 여기서 이동 연산을 통해 문제를 해결할 수 있다.
- 아래와 같이 구성하면 해결된다.
//Character.h
...
vector<unique_ptr<Item>> mItems;
//Character.cpp
...
void Character::AddItemToInventory(unique_ptr<Item> item)
{
mItems.push_back(move(item));
}
3. for문
- for문을 통해서 unique_ptr이 들어있는 배열을 순환할 때에도 아래 코드처럼 &를 붙여서 복사를 방지해야 한다.
//Character.h
...
vector<unique_ptr<Item>> mItems;
//Character.cpp
void Character::ShowItems()
{
for (const unique_ptr<Item>& item : mItems)
{
cout << item->GetName() << "\n";
}
}
'C++' 카테고리의 다른 글
static Keyword (0) | 2025.03.27 |
---|---|
텍스트 RPG 게임 만들기 (C++) (1) | 2025.01.16 |
C++ 면접 대비 정리 (0) | 2025.01.09 |
C++ 디자인 패턴 (1) | 2025.01.06 |
C++ TIL day 13 (1) | 2025.01.03 |