인벤토리 시스템
우선 과제 항목 중 필수 기능만 우선 구현하였습니다.
Inventory.h
// Inventory.h
#pragma once
#include <iostream>
template <typename T>
class Inventory
{
public:
Inventory(int capacity = 10)
{
if (capacity <= 0)
{
capacity_ = 1;
}
else
{
capacity_ = capacity;
}
size_ = 0;
pItems_ = new T[capacity_];
}
~Inventory()
{
delete[] pItems_;
pItems_ = nullptr;
}
void AddItem(const T& item)
{
if (size_ >= capacity_)
{
std::cout << "인벤토리가 꽉 찼습니다!" << std::endl;
return;
}
pItems_[size_] = item;
++size_;
}
void RemoveLastItem()
{
if (size_ <= 0)
{
std::cout << "인벤토리가 비어있습니다!" << std::endl;
return;
}
pItems_[size_ - 1].Clear();
--size_;
}
int GetSize() const
{
return size_;
}
int GetCapacity() const
{
return capacity_;
}
void PrintAllItems() const
{
if (size_ == 0)
{
std::cout << "비어있음" << std::endl;
return;
}
for (int i = 0; i < size_; ++i)
{
pItems_[i].PrintInfo();
}
}
private:
T* pItems_;
int capacity_;
int size_;
};
Item.h
// Item.h
#pragma once
#include <iostream>
#include <string>
class Item
{
public:
Item()
: name_(""), price_(0)
{
}
Item(const std::string& name, int price)
: name_(name), price_(price)
{
}
const std::string& GetName() const
{
return name_;
}
int GetPrice() const
{
return price_;
}
void Clear()
{
name_ = "";
price_ = 0;
}
void PrintInfo() const
{
std::cout << "[이름: " << name_ << ", 가격: " << price_ << "G]" << std::endl;
}
private:
std::string name_;
int price_;
};
Main.cpp
// Main.cpp
#include "Inventory.h"
#include "Item.h"
int main(void)
{
Inventory<Item>* itemInventory = new Inventory<Item>();
for (int i = 0; i < 11; ++i)
{
itemInventory->AddItem(Item("Item" + std::to_string(i), i * 100));
}
std::cout << "\n";
itemInventory->PrintAllItems();
std::cout << "\n";
for (int i = 0; i < 11; ++i)
{
itemInventory->RemoveLastItem();
}
std::cout << "\n";
itemInventory->PrintAllItems();
std::cout << "\n";
delete itemInventory;
return 0;
}
출력

왜 헤더에 구현했는가?
템플릿 template <typename T> 에서 T는 아직 정해지지 않은 상태입니다.
템플릿은 컴파일 시점에 생성되고 타입이 나중에 결정되기에 컴파일러가 구현을 항상 볼 수 있어야 합니다.
그래서 헤더에 구현까지 포함하여 사용하였습니다.
템플릿을 사용하지 않았을 때
class InventoryInt {
int items[10];
};
class InventoryDouble {
double items[10];
};
class InventoryString {
std::string items[10];
};
문제점
- 코드 중복 발생으로 로직은 똑같은데 타입만 다르거나 클래스를 계속 추가해야됨
- 수정할 때 전부 고쳐야 하는 문제점이 발생함
템플릿을 사용했을 때
template <typename T>
class Inventory
{
T items[10];
};
- 코드 재사용이 간편함
- 수정이 필요한 부분만 고치면되서 유지보수가 쉬움
- 컴파일 단계에서 타입 문제를 실행 전에 검수해줌
- 컴파일 시 코드 생성 하므로 성능이 좋음
- 새로운 타입 추가하기 간편함
마무리
내일 과제 제출 마감일이니 도전과제도 해보면서 전체적으로 다시한번 작성해보면서 해당 기능들이 왜 쓰이는지 제대로 파악해볼 예정입니다.
2026.03.18 도전기능 과제 추가
Inventory.h
// Inventory.h
#pragma once
#include <algorithm>
#include <iostream>
#include "Item.h"
template <typename T>
class Inventory
{
public:
~Inventory()
{
delete[] pItems_;
pItems_ = nullptr;
}
Inventory(int capacity = 10)
{
if (capacity <= 0)
{
capacity_ = 1;
}
else
{
capacity_ = capacity;
}
size_ = 0;
pItems_ = new T[capacity_];
}
void AddItem(const T& item)
{
if (size_ >= capacity_)
{
Resize(capacity_ * 2);
}
pItems_[size_] = item;
++size_;
}
void RemoveLastItem()
{
if (size_ <= 0)
{
std::cout << "인벤토리가 비어있습니다!" << std::endl;
return;
}
--size_;
}
int GetSize() const
{
return size_;
}
int GetCapacity() const
{
return capacity_;
}
void PrintAllItems() const
{
if (size_ == 0)
{
std::cout << "비어 있다!" << std::endl;
return;
}
for (int i = 0; i < size_; ++i)
{
pItems_[i].PrintInfo();
}
}
void Resize(int newCapacity)
{
if (newCapacity <= capacity_)
{
return;
}
T* pNewItems = new T[newCapacity];
for (int i = 0; i < size_; ++i)
{
pNewItems[i] = pItems_[i];
}
delete[] pItems_;
pItems_ = pNewItems;
capacity_ = newCapacity;
}
void SortItems()
{
std::sort(pItems_, pItems_ + size_, compareItemsByPrice);
}
Inventory(const Inventory<T>& other)
{
capacity_ = other.capacity_;
size_ = other.size_;
pItems_ = new T[capacity_];
for (int i = 0; i < size_; ++i)
{
pItems_[i] = other.pItems_[i];
}
}
void Assign(const Inventory<T>& other)
{
if (this == &other)
{
return;
}
delete[] pItems_;
capacity_ = other.capacity_;
size_ = other.size_;
pItems_ = new T[capacity_];
for (int i = 0; i < size_; ++i)
{
pItems_[i] = other.pItems_[i];
}
}
private:
T* pItems_;
int capacity_;
int size_;
};
Item.h
// Item.h
#pragma once
#include <iostream>
#include <string>
class Item
{
public:
Item();
Item(const std::string& name, int price);
const std::string& GetName() const;
int GetPrice() const;
void PrintInfo() const;
private:
std::string name_;
int price_;
};
inline bool compareItemsByPrice(const Item& a, const Item& b)
{
return a.GetPrice() < b.GetPrice();
}
Item.cpp
// Item.cpp
#include "Item.h"
Item::Item() : name_(""), price_(0)
{
}
Item::Item(const std::string& name, int price)
: name_(name), price_(price)
{
}
const std::string& Item::GetName() const
{
return name_;
}
int Item::GetPrice() const
{
return price_;
}
void Item::PrintInfo() const
{
std::cout << "[이름: " << name_ << ", 가격: " << price_ << "G]" << std::endl;
}
Main.cpp
// Main.cpp
#include "Inventory.h"
#include "Item.h"
struct ItemData
{
std::string name;
int price;
};
ItemData itemList[] =
{
{"철검", 1000},
{"철방패", 800},
{"생명력 포션", 50},
{"마나 포션", 80},
{"스태미나 포션", 50},
{"공격력 증가 포션", 200},
{"고블린의 귀", 10},
{"고블린의 눈", 15},
{"고블린의 가죽", 15},
{"오크의 가죽", 100},
{"고블린의 조잡한 돌검", 1},
{"오크의 대검", 2000},
{"거미줄", 2},
{"양털", 2},
{"우유", 3},
{"빵", 5},
{"숙소 열쇠", 0},
{"손질이 필요한 갑옷", 3000},
{"손질이 필요한 건틀렛", 2000},
{"손질이 필요한 그리브", 2000}
};
int main(void)
{
Inventory<Item>* itemInventory = new Inventory<Item>();
for (int i = 0; i < 11; ++i)
{
itemInventory->AddItem(Item(itemList[i].name, itemList[i].price));
}
std::cout << "\n==== 필수 과제 인벤토리 ====\n";
itemInventory->PrintAllItems();
std::cout << "\nItemCapacity : " << itemInventory->GetCapacity() << std::endl;
itemInventory->Resize(25);
for (int i = 0; i < 20; ++i)
{
itemInventory->AddItem(Item(itemList[i].name, itemList[i].price));
}
std::cout << "\n==== 도전 과제 인벤토리 ====\n";
itemInventory->PrintAllItems();
std::cout << "\nItemCapacity : " << itemInventory->GetCapacity() << std::endl;
std::cout << "\n==== 정렬 후 인벤토리 ====\n";
itemInventory->SortItems();
itemInventory->PrintAllItems();
std::cout << "\n==== 복사된 인벤토리 ====\n";
Inventory<Item>* itemInventory2 = new Inventory<Item>(*itemInventory);
itemInventory2->PrintAllItems();
delete itemInventory;
itemInventory = nullptr;
delete itemInventory2;
itemInventory2 = nullptr;
return 0;
}
추가 및 변경점
- Item 클래스 같은 경우 헤더에 다 구현하던걸 헤더와 cpp로 나눠서 다시 구현하엿음
- 인벤토리가 가득 찻을 때 Resize를 통해 메모리 재할당 받아 2배 만큼 가방 공간이 늘어나게 함
- std::sort를 통해 정렬하는 법을 배움
- 깊은 복사...부분은 더 공부가 필요하다
'학습일지 > C와 C++' 카테고리의 다른 글
| C++ 콘솔 RPG 만들기 (0) | 2026.03.19 |
|---|---|
| C++ 스마트 포인터 (0) | 2026.03.18 |
| C++ Debugging (0) | 2026.03.16 |
| Moderen C++ (1) | 2026.03.15 |
| C++ Vector (0) | 2026.03.14 |