在 C++ 中使用 Base 和 Derived 类 的范围

Scope with Base and Derived Classes in C++

我很难理解我在这里遇到的问题。这是学校课程的作业。我在笔记本电脑上编写代码,然后 compile/test/submit 在学校的服务器上。

我目前在 clion 中编写代码。当我在 Mac 的终端上 运行 gcc -vg++ -v 时,我得到以下信息:

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0

运行 在学校的服务器上我得到相同的命令:

gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)

我正在不同版本的 gcc 上编译,不确定这是否会影响我的问题。继续...

int main() {
    int choice; // Used to get creature selection from user
    Creature *creature1, *creature2; // Objects created

    printCreatureList(); // Prints list of creatures for players to select from

    choice = getIntFromUser(5); // Gets user choice for creature selection
    if (choice == 1) {
        Goblin newGob1;
        creature1 = &newGob1;
        newGob1.setStats();

        cout << "Created " << creature1->getName() << " as player 1's creature.\n";
// more if-else, and repeat for player 2 ...
    }

现在,玩家 1 和玩家 2 各自创建了一个准备战斗的生物。请注意以备后用,creature1->getName() 在这里可以正常运行。这是给我带来问题的战斗循环部分。请注意,还有另一个版本,玩家 2 进攻,玩家 1 防守。

    do { // Enter game loop
        cout << endl << "\nTurn #" << i << ", Player 1 (" << creature1->getName() << ") attacking Player 2 (" << creature2->getName() << ")";
        i++;

        p1Attacks(*creature1, *creature2, *p1Achilles, *p2Achilles); // Player 1 attacks, player 2 defends

        if (creature2->getStrength() <= 0) { //Check if creature2 was defeated
            cout << "\n\t***Player 2's creature has taken fatal damage***" << endl;
            cout << "\n\t* * * Player 1 (" << creature1->getName() << ") has won the battle * * *" << endl;
            winCondition = false;
            break;

       // advances on to p2Attacks
     } while (winCondition);

我的 p1Attack 和 p2Attack 格式相似:

void p1Attacks(Creature &p1, Creature &p2, bool &p1AchillesInjury, bool &p2AchillesInjury)

p1Attacks/p2Attacks 工作正常,所有数学计算结果都很完美。但是当我 运行 在学校服务器上战斗时, gcc 4.4.7 20120313 我看到:

Turn #1, Player 1 () attacking Player 2 () Player 1's attack roll: 7 Player 2's defend roll: 1 Player 1's damage output: 6 Player 2's armor: 3 Player 2 damage taken: 3 Player 2 new strength: 5

第一行不正确,如果他们各自创建了各自的字符,则应显示为 Turn #1, Player 1 (The Barbarian) attacking Player 2 (Reptile)。在我的本地机器上,代码 运行s 是正确的,并在圆括号中正确拼出了名字。

我的生物 class 和来自 creature.cpp 的 .setStats() 示例:

class Creature {
public:
    Creature() {}
/*
    Functions:      changeStrength()
    Description:    Change strength attribute for creature by reducing value
    Parameters:     reduceStrengthBy
    Preconditions:  None
    Postconditions: Strength is reduced
*/
    void changeStrength(int reduceStrengthBy);

    int getAttackDice()     { return attackDice; }
    int getAttackSides()    { return attackSides; }

    int getDefenseDice()    { return defenseDice; }
    int getDefenseSides()   { return defenseSides; }

    int getArmor()          { return armor; }
    int getStrength()       { return strength; }

    std::string getName()   { return name; }

    bool getDodge()         { return dodge; }

protected:
    int attackDice;
    int attackSides;

    int defenseDice;
    int defenseSides;

    int armor;
    int strength;

    std::string name;

    bool dodge;
};

void Reptile::setStats() {
    attackDice = 3;
    attackSides = 6;
    defenseDice = 1;
    defenseSides = 6;
    armor = 7;
    strength = 18;
    name = "The Reptile";
    dodge = false;
}

所以我的最终问题是,为什么 creature1->getName() 行在早期 if statement 时在我的笔记本电脑和学校服务器上都能正常运行,但只能在我的本地计算机上运行而无法正常运行稍后在远程服务器上工作(p1Attack 附近)?

如果某些东西在一台机器上工作但在另一台机器上不能工作,你可以确定你已经成为未定义行为的受害者。

事实上,您正在使用悬挂指针。基本上,归结为:

int main(int, char**) {
  int * pointer; // uninitialised, don't use
  if (someCondition) {
    int object = 42;
    pointer = &object; // assigned to point to an object, can be used
  } // object goes out of scope here
  // pointer is dangling, don't use
  cout << *pointer << endl; // oops
  return 0;
}

要解决这个问题,您需要将对象存储在不受自动内存管理影响的地方(例如在堆上),或者重新安排代码以利用它。