//***********************************
// Item
//***********************************
enum ItemRarity
{
IR_None,
IR_Normal,
IR_Rare,
IR_Unique,
};
enum ItemType
{
IT_None,
IT_Weapon,
IT_Armor,
};
class Item
{
public:
Item();
Item(ItemType itemType);
virtual ~Item();
ItemType GetItemType() { return _itemType; };
virtual void PrintInfo();
protected:
int _itemId = 0;
ItemRarity _rarity = IR_Normal;
ItemType _itemType = IT_None;
};
//***********************************
// Weapon
//***********************************
class Weapon : public Item
{
public:
Weapon();
~Weapon();
virtual void PrintInfo() override;
void SetDamage(int damage) { _damage = damage; };
int GetDamage() { return _damage; };
private:
int _damage = 0;
};
//***********************************
// Armor
//***********************************
class Armor : public Item
{
public:
Armor();
~Armor();
virtual void PrintInfo() override;
void SetDefence(int defence) { _defence = defence; };
int GetDefence() { return _defence; };
private:
int _defence = 0;
};
랜덤으로 Weapon객체를 가리키는 포인터를 반환할지
아니면 Armor객체를 가리키는 포인터를 반환할지
Item* DropItem()
{
if (rand() % 2 == 0)
{
Weapon* weapon = new Weapon();
return weapon;
}
else
{
Armor* armor = new Armor();
return armor;
}
}
main함수
int main()
{
srand((unsigned)time(0));
Item* item = DropItem();
ItemType itemType = item->GetItemType();
if (itemType == IT_Weapon)
{
Weapon* w1 = (Weapon*)item;
cout << w1->GetDamage() << endl;
}
else if (itemType == IT_Armor)
{
Armor* a1 = (Armor*)item;
cout << a1->GetDefence() << endl;
}
item->PrintInfo();
}
DropItem 함수에서 랜덤으로 다른 객체 포인터를 반환하기에
ItemType이라는 멤버변수를 둬서 해당 타입에 맞게 캐스팅을 해줘야함
실수로 해당 타입으로 분리를 시켜주지않고
int main()
{
srand((unsigned)time(0));
Item* item = DropItem();
ItemType itemType = item->GetItemType();
Weapon* w2 = (Weapon*)item;
w2->SetDamage(20);
item->PrintInfo();
}
이런식으로 코드를 짠다면 만약 반환 된 것이 Armor*라면
C++에서는
객체의 메모리 구조에서 Armor 클래스에 정의된 멤버 변수 중 SetDamage과 메모리 레이아웃에서 가장 가까운 변수를 찾아 20을 설정하게 됩니다.