티스토리 뷰
🟩 오늘의 목표
- Item 추상 클래스를 설계하여 모든 아이템의 공통 속성인 이름과 개수를 관리하는 최상위 규격을 만든다.
- HpPotion과 AtkPotion 자식 클래스를 구현하며 부모의 순수 가상 함수를 재정의(Override)하는 법을 익힌다.
- 초기화 리스트를 통한 부모 생성자 호출 방식과 데이터 무결성 확보를 위한 보정(Clamping) 로직을 복습한다.
- 헤더 파일과 소스 파일을 분리하여 모듈화된 프로젝트 관리 방식을 실습한다.
🟧 1. 아이템 시스템의 추상화와 모듈화 설계
🟦 Item 추상 클래스 설계
모든 아이템의 공통 속성인 ItemName_과 count_를 관리하는 최상위 클래스를 설계했다. Use() 함수를 순수 가상 함수로 선언하여 자식 클래스들이 각자 고유한 기능을 반드시 구현하도록 규격을 정의했다. 이를 통해 객체 지향의 다형성을 확보하고 향후 새로운 아이템 추가가 용이한 구조를 만들었다.
🟦 파일 분리 및 모듈화
프로젝트의 관리 효율성을 높이기 위해 헤더 파일(.h)과 소스 파일(.cpp)로 기능을 분리하여 구현했다. 또한 class Player;와 같은 전방 선언을 활용하여 순환 참조 문제를 방지하고 컴파일 속도를 최적화했다.
🟧 2. 주요 변경 및 문제 해결 사항
🟦 생성자 초기화 리스트 활용
자식 클래스 생성 시 부모 생성자를 명시적으로 호출하는 초기화 리스트 문법을 사용하여 멤버 변수에 쓰레기 값이 할당되던 문제를 해결했다. 부모 클래스의 생성자가 먼저 실행되어 기초 데이터를 안전하게 설정한 뒤 자식의 추가 데이터를 초기화하는 흐름을 확인했다.
🟦 데이터 무결성 확보와 보정 로직
HpPotion 사용 시 현재 체력이 최대치를 초과하지 않도록 하는 보정(Clamping) 로직을 추가했다. 또한 아이템 개수가 0일 경우 사용되지 않도록 방지 로직을 구현하여 게임 논리의 오류를 차단했다. 중복되던 변수들을 부모 클래스로 이동시키는 리팩토링을 통해 유지보수성을 향상했다.
🟧 3. 핵심 코드 구현 및 해설
// Item.cpp
#include "Item.h"
#include "Player.h"
Item::Item(std::string ItemName, int count) : ItemName_(ItemName), count_(count) {}
Item::~Item() {}
HpPotion::HpPotion(std::string ItemName, int Count) : Item("HP 포션", Count) {}
void HpPotion::Use(Player& player) {
int CurrentHp = player.GetHP();
int Maxhp_ = player.GetMaxHP();
if (CurrentHp < Maxhp_ && count_ > 0) {
std::cout << ItemName_ << " 사용! " << HealAmount_ << " 회복." << std::endl;
CurrentHp += HealAmount_;
if (CurrentHp > Maxhp_) CurrentHp = Maxhp_; // Clamping 로직
player.SetHP(CurrentHp);
std::cout << "현재 체력 : " << player.GetHP() << " | 남은 갯수 : " << --count_ << std::endl;
} else if (count_ <= 0) {
std::cout << "아이템이 부족합니다." << std::endl;
} else {
std::cout << "이미 체력이 가득 차 있습니다." << std::endl;
}
}
AtkPotion::AtkPotion(std::string ItemName, int Count) : Item("공격력 포션", Count) {}
void AtkPotion::Use(Player& player) {
if (count_ > 0) {
int nextAtk = player.GetAttack() + AtkAmount_;
player.SetAttack(nextAtk);
std::cout << ItemName_ << " 사용! 공격력 " << AtkAmount_ << " 증가." << std::endl;
std::cout << "현재 공격력 : " << player.GetAttack() << " | 남은 갯수 : " << --count_ << std::endl;
} else {
std::cout << "아이템이 부족합니다." << std::endl;
}
}
🟧 4. 설계 의도 및 주의 사항
🟦 추상 클래스와 인터페이스의 역할
Item 클래스는 직접 객체를 생성할 수 없으며 오직 상속을 위한 규격으로만 존재하게 설계했다. 모든 아이템이 Use(Player&)라는 동일한 인터페이스를 가지므로, 개발자는 아이템의 구체적인 종류를 몰라도 Item* 포인터만으로 모든 아이템의 기능을 일관되게 실행할 수 있음을 이해했다. 공격력 증가는 현재 영구 반영되도록 구현했으나, 향후 기간제 버프 시스템을 도입할 여지를 남겨두었다.
🟫 오늘 느낀 점
추상 클래스와 상속을 활용해 아이템 시스템의 뼈대를 구축하며 객체 지향의 다형성이 코드의 재사용성과 확장성에 얼마나 기여하는지 깊이 이해하게 되었다.
'내일배움캠프 Unreal_7기 > 본캠프' 카테고리의 다른 글
| TIL - 26일차 (0) | 2026.01.05 |
|---|---|
| TIL - 25일차 (0) | 2026.01.02 |
| TIL - 23일차 (0) | 2025.12.30 |
| TIL - 22일차 (0) | 2025.12.29 |
| TIL - 21일차 (0) | 2025.12.29 |

