1. 템플릿(Template): 타입을 초월한 설계도
템플릿은 데이터 타입만 비워둔 '미완성 설계도'입니다. 컴파일 시점에 사용자가 넣은 타입에 맞춰 실제 코드가 생성됩니다.
- 왜 쓰는가?: Player 공격, Monster 공격 함수를 따로 만들지 않고, Battack(T& give, U& take) 하나로 모든 전투 상황을 처리하기 위함입니다.
- 주의점: 템플릿 함수 내부에서 target->Inventory를 참조한다면, 인자로 들어오는 모든 타입(T, U)이 반드시 Inventory 멤버를 가지고 있어야 합니다.
2. 클래스 상속과 생성자의 비밀
부모와 자식 관계에서 메모리가 어떻게 생성되는지 이해하는 것이 오늘 에러 해결의 핵심이었습니다.
- 부모 없는 자식 없다: 자식 클래스(Monster)의 생성자가 호출될 때, 부모 클래스(Entity)의 생성자가 가장 먼저 실행되어야 합니다.
- 초기화 리스트: 부모에게 기본 생성자가 없다면, 자식 생성자에서 : Entity(n, h, ...)와 같이 부모에게 필요한 인자를 명시적으로 전달해야 합니다.
3. 멤버 변수로서의 객체와 기본 생성자
클래스 내부에 다른 객체(Item dropitem)를 변수로 들고 있을 때의 규칙입니다.
- 전방 선언의 한계: struct Item;처럼 이름만 알려주면 포인터(Item*)는 만들 수 있지만, 실제 변수(Item dropitem)는 크기를 알 수 없어 선언이 불가능합니다. (정의를 위로 올려야 함)
- 기본 생성자의 필요성: Entity를 만들 때 아이템을 바로 넣어주지 않는다면, Item 구조체에 내용이 비어있는 Item() {} 생성자가 있어야 컴파일러가 안심하고 공간을 확보합니다.
4. const와 함수의 자격 증명 (Qualifier)
오늘 가장 까다로웠던 "type qualifiers that are not compatible" 에러의 정체입니다.
- const 객체: "내용을 절대 바꾸지 않겠다"고 약속된 객체입니다. (const auto& item)
- const 함수: void PrintInfo() const { ... }처럼 뒤에 const가 붙은 함수만 const 객체에서 호출할 수 있습니다.
- 결론: 데이터를 출력만 하는 함수는 무조건 뒤에 const를 붙이는 습관을 들여야 합니다.
5. [실전 예제] 오늘 완성한 RPG 기초 구조
오늘 에러를 모두 수정하고 다듬은 최종적인 클래스 설계입니다.
C++
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Item {
string name;
int price;
Item() : name("없음"), price(0) {} // 기본 생성자: Entity 생성 시 필요
Item(string n, int p) : name(n), price(p) {}
void PrintInfo() const { // const 보증서: 인벤토리 출력 시 필요
cout << name << " (" << price << "G)" << endl;
}
};
class Entity {
public:
string name;
int hp, power, defence;
vector<Item> Inventory; // 모든 개체는 가방을 가질 수 있음 (Battack 에러 방지)
Item dropitem; // 몬스터가 죽을 때 줄 아이템
Entity(string n, int h, int p, int d)
: name(n), hp(h), power(p), defence(d) {}
virtual ~Entity() {} // 가상 소멸자: 상속 시 필수!
};
class Monster : public Entity {
public:
// 부모 생성자 호출 후, 본인만의 dropitem 저장
Monster(string n, int h, int p, int d, Item i)
: Entity(n, h, p, d) { dropitem = i; }
};
💡 오늘의 깨달음 (복습 포인트)
- 에러 메시지를 읽는 법: not a member of는 클래스 설계도에 해당 변수가 없다는 뜻이고, qualifiers not compatible은 const 약속이 깨졌다는 뜻이다.
- 공통 멤버는 부모에게: 플레이어와 몬스터가 공통으로 하는 행동(공격, 방어, 사망)이나 속성(이름, 체력, 인벤토리)은 부모 클래스인 Entity에 두는 것이 템플릿 함수를 쓸 때 훨씬 편하다.
- 메모리 해제의 책임: new로 동적 할당을 했다면, 그 객체를 가리키는 포인터가 사라지기 전에 반드시 delete를 호출하자.
'TIL' 카테고리의 다른 글
| [UE5] 외부 툴 없이 엔진 내에서 애니메이션 수정 및 몽타주 적용하기 (0) | 2026.05.13 |
|---|---|
| UE5 협업을 위한 Git 사용법 학습 (0) | 2026.05.12 |
| [C++ ] 템플릿(Template)과 STL 컨테이너정리 (0) | 2026.05.08 |
| [C++] 상속과 다형성의 핵심: 추상 클래스부터 가상 소멸자까지 (0) | 2026.05.07 |
| [C++] 함수 오버로딩, 템플릿, 그리고 STL 컨테이너 기초 정리 (0) | 2026.05.06 |