c++ 对象数组在方法中更改后会重置[重复]

问题描述 投票:0回答:1

我是c++新手,我在大学学过java。我试图从一个小型的初学者项目开始。一款控制台角色扮演游戏。我创建了一个 GameEntity 类,一个继承 GameEntity 类的玩家类和一些枚举:GameType、Stats

int main(){

    GameEntity *opponent = new GameEntity("enemy", 20, 3, 4);
    Player *player = new Player("player", 40, 4, 4);

    //initialize combatStats
    player->prepareForCombat();
    opponent->prepareForCombat();

    int r = 0;
    while(!player->isDead() && !opponent->isDead()){
        player->chooseMove(*opponent, r);
        opponent->chooseMove(*player, r);
        r++;
    }
    if(!player->isDead()){
        cout << "you won!";
    }else{
        cout << "you lost!";
    }

    return 0;
}

我的问题: 我有一个包含所有统计数据的数组,包括马力。

int combatStats[7];
以及减少 GameEntity hp 的方法:

void decreaseHp(int damage)
    {
        if(damage <= 0)return;
        combatStats[Hp] = combatStats[Hp] - damage;
        cout << name << ": gets "<< damage << " damage." << '\n';
        cout << name << ": current health: " << getHp() << '\n';
        if(combatStats[Hp] <= 0){
            die();
        }
    }

该方法将 hp 更改为正确的值并将其打印出来,但在该方法停止后,它又变回其初始状态。

我预计数组不会自行重置其值。

它有一个私有访问修改器,所以我尝试将其更改为公共,但它什么也没做。

这是完整代码:

//#include "GameEntity.cpp";
//#include "Player.cpp";
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::string;

enum Stats{
    Hp = 0,Mind = 1,Str = 2,Dex = 3,End = 4,Int = 5,Wis = 6
};
enum GameType{
    thrust,slash,bludgeon,light,dark,heat,cold, mind, arcane
};

class GameEntity{
    protected:
        int baseStats[7];
        string name;
        bool isAllive = true;
        int blockVal = 0;
        
    public:
        GameEntity(string name, int hp, int pVal, int mVal){
            this->name = name;
            baseStats[Hp] = hp;
            baseStats[Mind] = 100;
            baseStats[Str] = pVal;
            baseStats[Dex] = pVal;
            baseStats[End] = hp/10;
            baseStats[Int] = mVal;
            baseStats[Wis] = mVal;
        }
        int combatStats[7];
        string getName(){return name;}
        int getHp(){return combatStats[Hp];}
        int getDex(){return combatStats[Dex];}
        int getInt(){return combatStats[Int];}
        int getEnd(){return combatStats[End];}
        int getStr(){return combatStats[Str];}
        int getWis(){return combatStats[Wis];}
        int getMind(){return combatStats[Mind];}
        void incrementDex(int i){combatStats[Dex] += i;}
        void incrementInt(int i){combatStats[Int]+= i;}
        void incrementEnd(int i){combatStats[End]+= i;}
        void incrementStr(int i){combatStats[Str]+= i;}
        void incrementWis(int i){combatStats[Wis]+= i;}
        void decrementDex(int d){combatStats[Dex]-= d;}
        void decrementInt(int d){combatStats[Int]-= d;}
        void decrementEnd(int d){combatStats[End]-= d;}
        void decrementStr(int d){combatStats[Str]-= d;}
        void decrementWis(int d){combatStats[Wis]-= d;}

    void chooseMove(GameEntity target, int round){
        cout << name << " health: " << combatStats[Hp] << '\n';
        blockVal = 0;
        if(round%2 == 0){
            cout << name << ": does a slash attack." << '\n';
            target.damage(10 , GameType::slash);
        }
        else if(round == 5 || round == 12){
            heal(5, GameType::light);
        }
        else{
            block(8);
        }
    }
    void damage(int damage, GameType type){
        if(blockVal > damage){
            blockVal -= damage;
            cout << name << ": blocked "<< damage << " damage." << '\n';
            damage = 0;
        }else if(blockVal < damage){
            damage -= blockVal;
            cout << name << ": blocked "<< blockVal << " damage." << '\n';
            blockVal = 0;
        }else{
            cout << name << ": blocked all damage. ("<< blockVal << ")" << '\n';
            damage = 0;
            blockVal = damage;
        }

        switch(type){
            case GameType::arcane: 
                decreaseHp(damage);
                break;
            default:
                cout << name << ": endured "<< combatStats[End] << " damage." << '\n';
                decreaseHp(damage-combatStats[End]);
                break;
        }
    }
    
    void heal(int healing, GameType type){
        if(type == GameType::light){
            combatStats[Hp] += healing;
            cout << name << ": healed by "<< healing << '\n';
        }
        if(combatStats[Hp] > baseStats[Hp]){
            combatStats[Hp] = baseStats[Hp];
        }
    }
    void block(int block){
        blockVal = block;
        cout << name << ": prepares to block." << '\n';
    }

    bool isDead(){
        return !isAllive;
    }

    void prepareForCombat(){
        combatStats[Hp] = baseStats[Hp];
        combatStats[Mind] = baseStats[Mind];
        combatStats[Str] = baseStats[Str];
        combatStats[Dex] = baseStats[Dex];
        combatStats[End] = baseStats[End];
        combatStats[Int] = baseStats[Int];
        combatStats[Wis] = baseStats[Wis];
    }
    
    void decreaseHp(int damage)
    {
        if(damage <= 0)return;
        combatStats[Hp] = combatStats[Hp] - damage;
        cout << name << ": gets "<< damage << " damage." << '\n';
        cout << name << ": current health: " << getHp() << '\n';
        if(combatStats[Hp] <= 0){
            die();
        }
    }

    void die(){
        cout << name << ": died" << '\n';
        isAllive = false;
    }
};
class Player : public GameEntity
{
    public:
        using GameEntity::GameEntity;
        //using GameEntity::isDead;
        void chooseMove(GameEntity target, int round){
            cout << name << " health: " << combatStats[Hp] << '\n';
            blockVal = 0;
            cout <<"System: what do you want to do?" << '\n';
            cout <<"1) slash attack" << '\n';
            cout <<"2) punch" << '\n';
            cout <<"3) riposte" << '\n';
            cout <<"4) heal" << '\n';
            cout <<"5) block" << '\n';
            string input;
            cin >> input;
            switch (stoi(input))
            {
            case 1:
                cout << name << ": does a slash attack." << '\n';
                target.damage(10 , GameType::slash);
                break;
            case 2:
                cout << name << ": punches " << target.getName() << " really hard"<< '\n';
                target.damage(4 , GameType::bludgeon);
                block(2);
                break;
            case 3:
                cout << name << ": hits " << target.getName() << " and retracts, really fast"<< '\n';
                target.damage(7, GameType::thrust);
                block(5);
                break;
            case 4:
                cout << name << ": channels the light element"<< '\n';
                target.damage(7, GameType::thrust);
                heal(4, GameType::light);
                break;
            case 5:
                block(12);
            
            default:
                break;
            }
        }
};

int main(){

    GameEntity *opponent = new GameEntity("enemy", 20, 3, 4);
    Player *player = new Player("player", 40, 4, 4);

    player->prepareForCombat();
    opponent->prepareForCombat();

    int r = 0;
    while(!player->isDead() && !opponent->isDead()){
        player->chooseMove(*opponent, r);
        opponent->chooseMove(*player, r);
        r++;
    }
    if(!player->isDead()){
        cout << "you won!";
    }else{
        cout << "you lost!";
    }

    return 0;
}

c++ arrays class reset
1个回答
1
投票

问题来了

void chooseMove(GameEntity target, int round){

正如怀疑的那样,您正在更改

target
,这是您实际想要更改的对象的 副本。只需更改您的代码即可使用参考

void chooseMove(GameEntity& target, int round){

在 Java 中,所有对象变量自动都是引用。在 C++ 中情况并非如此。这是学习 C++ 意味着放弃 Java 的第一条线索。

还有一个免费的建议,不要在这里使用

new
,只是

GameEntity opponent("enemy", 20, 3, 4);
Player player("player", 40, 4, 4);

(以及随之而来的其余部分的变化

main
)。

© www.soinside.com 2019 - 2024. All rights reserved.