Доступ из одного класса к полям другого

209
23 декабря 2017, 05:57

Здравствуйте.
Пытаюсь реализовать примитивный tower defence. Необходимо в методах класса Tower иметь доступ к полям класса Enemy. К примеру, в методе shoot класса Tower иметь доступ к полю health класса Enemy. Каким образом это реализовать наиболее оптимально и правильно?

class Enemy
{
public:
    Enemy();
    void move();
    void setHealth();
    float getHealth();
private:
    float health;
    float speed;
};
class Tower
{
public:
    Tower();
    void shoot();
private:
    float damage;
    float cooldown;
};

UPD: На данном этапе дошел до такого. Кто что скажет?

void Tower::shoot(Enemy &enemy)
{
   while (enemy.getHealth() >= 0) {
      enemy.setHealth(enemy.getHealth() - damage);
   }
}
Answer 1

Оптимальность и правильность зависит от целей и дальнейших ожиданий от классов.

Вы можете сделать так: сначала Tower а потом Enemy

class Tower{
//----------
//---------
};
class Enemy {
friend  void Tower::shoot(); 
//---------  
};

или написать так как вы, но сначала просто обьявить Tower и сделать его другом Enemy, а можно просто в Tower поменять спецификацию private на protected и сделать Enemy его наследником (скорее наследование стоит сделать закрытым).

Answer 2

Не нужно давать Tower доступ к полям класса Enemy. Это нарушение инкапсуляции. Здесь вам нужен обмен сообщениями. Логика такая - башня стреляет в противника, он получает урон. Подумаем о деталях этого процесса. Есть 2 отдельных подпроцесса:

1) башня стреляет - только она сама знает, как она может выстрелить.

2) противник получает урон - только он сам знает, как он от этого урона поведет себя.

Вот каждый из этих подпроцессов и надо отдельно смоделировать, например так:

void Tower::Shoot(ITarget *target)
{
  int power = CalculatePower(); //тут может быть любой расчет того, как сильно вы бьете, может зависеть от множества факторов
// ...  
//далее может быть еще куча кода дополнительного, отрисовка, например или еще что
// ...
  target->GetShot(power); //передаем врагу сообщение, что мы его ударили, и говорим, с какой силой
}
void ITarget::GetShot(int power)
{
  int damage = CalculateDamage(power, hp, armor);
  if (damage >= hp)
    Die();
  else
    hp -= damage;
// ...  
//тут может быть еще куча кода дополнительного, отрисовка, например или еще что
// ...
}
READ ALSO
Способы создания обьектов класса С++

Способы создания обьектов класса С++

Сколькими способами можно создать обьект класса на С++ в ООП?

219
DirectX9, освещение текстурированной модели

DirectX9, освещение текстурированной модели

Все делаю по технологии: создаю буфер вершин, задаю координаты вершин, координаты текстуры, нормалиБез освещения модель отрисовывается идеально

202
Поиск по содержимому файлов (С/C++ Linux)

Поиск по содержимому файлов (С/C++ Linux)

Задание следующее - В указанной директории найти обычные файлы, которые содержат одинаковые (по информации) строкиВывести: имя файла, права...

238
CMake не может найти заголовочный файл

CMake не может найти заголовочный файл

Используем для проекта GMPПри сборке проекта CMake выкидывает мне следующее:

212