예제 5. 0으로 나눔(Divided by Zero) 문제
int Knight::GetAttackDamage()
{
// hp 50% 계산식 => maxHp / hp = 2
int damage = _attack;
int ratio = _maxHp / _hp;
if (ratio > 2)
damage *= 2;
return damage;
}
HP 비율을 계산하는 ratio 변수가 있을 때, 최대 HP를 0인 현재 HP로 나누려고 해서 발생하는 문제이다.
이 때는 HP 비율을 계산하는 방법을 달리 만들어준다.
if (_maxHp == 0)
return damage;
int percentage = (_hp * 100) / _maxHp;
if (percentage <= 50)
damage *= 2;
return damage;
이 때 percentage 변수를 계산할 때 100을 먼저 앞에 곱해주거나 형 변환을 통해 float로 변환 후 계산해준다.
예제 6. 순환 호출 문제
void Knight::OnDamaged(Knight* attacker)
{
if (attacker == nullptr)
return;
// 반격 데미지 계산
int damage = attacker->GetAttackDamage();
AddHp(-damage);
// 반격
attacker->OnDamaged(this);
}
k1이 k2를 공격한 후 k2의 공격력을 계산해서 k1을 공격하고, 다시 데미지를 받은 k1이 k2를 공격하는 무한 순환에 빠지게 된다.
이 문제를 해결하기 위해서 공격력이 0이거나 객체가 죽음(_hp <= 0)이면 return을 반환하게 한다.
int damage = attacker->GetAttackDamage();
AddHp(-damage);
if (damage == 0)
return;
if (IsDead())
return;
attacker->OnDamaged(this);
예제 7. 가상 소멸자 문제(메모리 누수)
class Pet
{
public:
public:
int _petId;
char _data[4096];
};
// Pet.h
위에서 Pet 클래스로 생성된 객체들은 4096 바이트의 크기를 가진다.
#include "Archer.h"
#include "Pet.h"
Archer::Archer()
{
_pet = new Pet();
}
Archer::Archer(int hp) : Player(hp)
{
_pet = new Pet();
}
Archer::~Archer()
{
if (_pet != nullptr)
delete _pet;
}
그리고 무거운 Pet 객체들은 아쳐가 생성될 때 같이 생성된다.
소멸자를 가상 함수로 만들어주지 않아서 부모의 소멸자는 호출이 되지만 자식의 소멸자가 호출이 되지 않아 아쳐가 delete되지 않아 메모리를 잡아먹게 된다.
'기초 C++ 스터디 > 예제' 카테고리의 다른 글
9-3. STL - Vector 구현하기 (실습) (0) | 2023.06.14 |
---|---|
7-3. 디버깅 예제 #8 ~ 10 (0) | 2023.06.07 |
7-1. 디버깅 예제 #1 ~ 4 (0) | 2023.06.07 |
7-0. 디버깅 연습 (0) | 2023.06.07 |
6-6. Text RPG - OOP (0) | 2023.06.02 |