Я работаю над простым консольным приложением для создания прототипа метода расчета битвы между двумя большими отрядами средневековых солдат. Идея состоит в том, чтобы настроить расчеты и запустить программу несколько раз с разными параметрами, чтобы почувствовать ее и, если это то, что я хочу. В любом случае, к проблеме.
Каждая из двух единиц представлена классом единиц. Класс включает переменные для «атаки», «защиты», «тактики» и «размера отряда», а также некоторые другие, которые я комментирую и игнорирую, пока не исправлю эту проблему. Вот код для заголовка класса:
#ifndef UNITS_H
#define UNITS_H
#include <string>
#include <iostream>
class Unit
{
public:
int attack;
int defense;
int charge;
int brace;
int tactics;
int unit_size;
public:
bool isAlive;
std::string name;
Unit(std::string name_target)
{
name = name_target;
attack = 1;
defense = 1;
charge = 1;
brace = 1;
tactics = 1;
unit_size = 1;
isAlive = true;
}
float GetAttack() {return (float)attack;}
float GetDefense() {return (float)defense;}
float GetCharge() {return (float)charge;}
float GetBrace() {return (float)brace;}
float GetTactics() {return (float)tactics;}
float GetSize() {return (float)unit_size;}
void SetAttack(int change) {attack = change;}
void SetDefense(int change) {defense = change;}
void SetCharge(int change) {charge = change;}
void SetBrace(int change) {brace = change;}
void SetTactics(int change) {tactics = change;}
void SetSize (int change) {unit_size = change;}
void TakeCasualties (int casualties);
int Defend(Unit enemy, float base_chance, float base_multiplier);
void DisplayStats();
};
#endif // UNITS_H
Извините, если это небрежно, но я немного любитель.
Я бы включил .cpp код для класса, но там все работает нормально. Я сделал тестовые прогоны только со значениями по умолчанию без проблем. Единственная проблема, которую я имею, — это изменение значений после их построения.
В main.cpp у меня есть функция AssignStats (Unit unit_target), которую я вызываю после создания двух модулей. Я звоню каждому по очереди. Код для этого выглядит следующим образом:
void AssignStats (Unit unit_target)
{
int x;
cout << unit_target.name << endl;
cout << "Value for attack?" << endl;
cin >> x;
cout << x << endl;
unit_target.SetAttack(x);
cout << "Value for defense?" << endl;
cin >> x;
unit_target.SetDefense(x);
//unit_target.SetCharge(x);
//unit_target.SetBrace(x);
cout << "Value for tactics?" << endl;
cin >> x;
unit_target.SetTactics(x);
cout << "Value for size?" << endl;
cin >> x;
unit_target.SetSize(x);
}
Насколько я могу судить, этот код должен работать. Однако, когда я отображаю статистику каждого модуля позже, он показывает значения по умолчанию, введенные конструктором. Я не могу понять, почему мои функции Set не работают. Я переписал код немного раньше, чтобы проверить, правильно ли они вводят данные, например:
void Unit::SetAttack()
{
int x;
std::cout << "Input target value for attack." << std::endl;
std::cin >> x;
std::cout << x;
attack = x;
std::cout << attack;
}
Я бы ввел 10, и каждая из пар показала бы мне 10 обратно, даже ту, которая предположительно отображала переменную атаки класса, но позже, когда я вызвал DisplayStats (), он снова показал бы, что все по умолчанию ,
Может кто-нибудь более опытный, чем я, пожалуйста, проясните это?
Я думаю, что проблема в том, что функция AssignStats
принимает аргумент по значению
void AssignStats (Unit unit_target);
То есть функция имеет дело с копией исходного объекта. Сам оригинальный объект не изменяется.
Измените это следующим образом
void AssignStats (Unit &unit_target);
Я проверил ваши функции Set, и они работают нормально. Я думаю, что проблема заключается в
void AssignStats (Unit unit_target);
Вы передаете параметр Unit по значение, не ссылка. Это приводит к созданию локальной копии объекта Unit, которая инициализирует его новыми параметрами.
Вам нужно позвонить по ссылка:
void AssignStats (Unit &unit_target);
Таким образом, передается ссылка на исходный объект, и ваши функции Set () будут работать с ним.
Некоторые дополнительные советы вне вопроса:
В C ++ передача параметров по ссылке обычно предпочтительнее, чем передача по значению, потому что издержки передачи большого объекта по значению из-за копирования могут быть существенными.
Если вы используете методы установки / получения для установки параметров, эти параметры должны быть объявлены закрытыми или защищенными, а не общедоступными. Это один из аспектов объектно-ориентированной инкапсуляции — не допускайте изменения параметров вне объекта.
например, вы должны иметь
//or protected if you will subclass Unit later
private:
int attack;
int defense;
int charge;
int brace;
int tactics;
int unit_size;