C++: как получить доступ к переменной из определения другого класса

Я пытаюсь сделать небольшую игру про покемонов, которая, очевидно, включает в себя нападение на другого покемона. Не беспокойтесь о Типе; это просто ENUM.

В настоящее время не работает: состояние _reciever не меняется, ошибок нет.

Мой текущий не рабочий код:

class Pokemon
    {
    public:
        string Name;
        Type Type;
        int Health;

        Pokemon(string _name, Pokemons::Type _type, int _health)
        {
            Name = _name;
            Type = _type;
            Health = _health;
        }

        bool checkHealth()
        {
            if (Health <= 0)
            {
                return false;
            }

            return true;
        }
        void updateHealth(char _operator, int _amount)
        {
            switch (_operator)
            {
            case '+':
                Health = Health + _amount;
                break;
            case '-':
                Health = Health - _amount;
                break;
            case '*':
                Health = Health * _amount;
                break;
            case '/':
                Health = Health / _amount;
                break;
            }
        }

        void attackEnemy(Pokemon _reciever)
        {
            _reciever.Health = _reciever.Health - 5;
        }

    };
#include <iostream>
#include "Pokemon.h"

using namespace std;
using namespace Pokemons;

int main()
{
    Pokemon Charmender("Charmender", Fire, 45);
    Pokemon Bulbasaur("Bulbasaur", Water, 50);

    while (true) {
        Charmender.attackEnemy(Bulbasaur);
        cout << Bulbasaur.Health << endl;
    }
}

Ps: это мой первый вопрос о стеке, дайте мне знать, если я что-то пропустил

void attackEnemy(Pokemon _reciever) -- Вы передаете _reciever по значению, что означает, что функция attackEnemy работает с локальной копией, которая исчезает, как только эта функция возвращается. Другими словами, функция Bulbasaur не влияет на main. Но это должно быть описано в любой хорошей книге по C++, прямо в главах, посвященных передаче параметров.
PaulMcKenzie 14.02.2023 17:30

Timmmm 14.02.2023 17:31

Я бы предпочел создать общедоступный метод takeDamage(float damage), чтобы каждое существо могло вычислить, сколько урона оно получило (например, если вы позже реализуете какую-то механику «брони», тогда takeDamage будет внутренне уменьшать урон на некоторое значение перед вычитанием из здоровья

Alexey Larionov 14.02.2023 17:32

Вы пытаетесь изучить C++, исходя из фона Java или C#?

Sam Varshavchik 14.02.2023 17:33

Привет Сэм, это правильно, я некоторое время использую C#

Rick Huisman 14.02.2023 17:34

@RickHuisman Я некоторое время использую C# - это может объяснить, почему вы сделали ошибку, которую сделали. Передача таких параметров в C++ сильно отличается от C#. В C++ вы должны явно указать, что вы передаете объект по ссылке (поэтому поведение похоже на C#) — автоматически не предполагается, что вы хотите это сделать. Кроме того, это указывает на то, что вы используете C# в качестве модели при написании кода C++. Не делайте этого, так как вы сами видите, в какой беспорядок вы попадаете, пытаясь выполнить построчный перевод с C# (или любого другого языка) на C++.

PaulMcKenzie 14.02.2023 17:35

Привет, Пол и Тим. Ваш комбинированный ответ устранил проблему, как я могу установить, что это исправление?

Rick Huisman 14.02.2023 17:39

В этом случае вы окажете себе огромную услугу, если забудете все, что знали о C#, пока изучаете C++. C++ — это не C#, и он работает принципиально по-другому, например, в этой конкретной проблеме: в C++ все параметры функции передаются по значению. Предположение, что что-то работает в C++, потому что оно выглядит почти так же, как что-то выглядит в C#, всегда заканчивается плачевно.

Sam Varshavchik 14.02.2023 17:39

Спасибо, Пол, я буду иметь это в виду, и, кстати, отличное время отклика!

Rick Huisman 14.02.2023 17:40

@RickHuisman - FWIW, передача параметров всегда будет сбивать с толку начинающего программиста на C++, который знает C# или Java, но не читал внимательно о том, как работает C++, когда дело доходит до передачи параметров. И то же самое можно сказать и наоборот: программист на C++, который пишет код на C# или Java, ожидая, что функция будет работать в локальной копии, также с треском провалится.

PaulMcKenzie 14.02.2023 17:41

На самом деле не все параметры в C# передаются по ссылке. Просто все объекты в C# на самом деле являются указателями, а не реальными объектами (Java работает точно так же). И указатели передаются по значению. Эквивалентный код C++ будет работать точно так же.

Sam Varshavchik 14.02.2023 17:42

Лично я согласен с тем, что «вы сделаете себе огромную, огромную услугу, если забудете все, что знаете о C#». Верно, обратно в мою коробку.

Bathsheba 14.02.2023 17:48
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги &lt;ul&gt; и &lt;li&gt; для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
1
12
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

void attackEnemy(Pokemon _reciever)
        {
            _reciever.Health = _reciever.Health - 5;
        }

При таком подходе _receiver уходит в конце вашего метода. Чтобы получить постоянные изменения, вы можете передать по ссылке:

void attackEnemy(Pokemon &_reciever)
        {
            _reciever.Health = _reciever.Health - 5;
        }

Другие вопросы по теме