简体   繁体   English

C ++中的基类和派生类的范围

[英]Scope with Base and Derived Classes in C++

I am struggling to understand what issue I am having here. 我正在努力了解我在这里遇到的问题。 This is an assignment for a course at school. 这是学校课程的一项任务。 I write my code on my laptop, and compile/test/submit it on the school's server. 我将代码写在笔记本电脑上,然后在学校的服务器上进行编译/测试/提交。

I currently write my code in clion. 我目前用clion编写代码。 When I run gcc -v or g++ -v on my Mac's terminal I get the following: 在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

Running the same command on the school's server I get: 我在学校的服务器上运行相同的命令:

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

I'm compiling on different version of gcc, not sure if that influences my issue. 我正在使用其他版本的gcc进行编译,不确定是否会影响我的问题。 Onwards... 向前...

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 ...
    }

Now, player 1 and player 2 each have a creature created that is ready to fight. 现在,玩家1和玩家2各自都有一个准备战斗的生物。 Note for later use, creature1->getName() functions correctly here. 请注意,稍后使用该creature1->getName()可以正常工作。 Here is the portion of the fight loop that gives me an issue. 这是战斗循环中给我一个问题的部分。 Note that there is another version of this where player 2 attacks, and player 1 defends. 请注意,还有另一个版本,其中玩家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);

My p1Attack and p2Attack have similar formats: 我的p1Attack和p2Attack具有相似的格式:

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

the p1Attacks/p2Attacks work correctly, and all the math comes out perfect. p1Attacks / p2Attacks正常工作,并且所有数学运算都非常完美。 But when I run the fight on my schools server, gcc 4.4.7 20120313 I see: 但是,当我在学校服务器上运行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

The first line is incorrect, it should read Turn #1, Player 1 (The Barbarian) attacking Player 2 (Reptile) if they each created those respective characters. 第一行是不正确的,如果他们分别创建了各自的角色,则应该读Turn #1, Player 1 (The Barbarian) attacking Player 2 (Reptile) On my local machine, the code runs correct and spells out the names in parentheses as it should. 在我的本地计算机上,代码可以正确运行,并按需要在括号中拼写出名称。

My creature class and an example of .setStats() from creature.cpp: 我的生物类以及生物.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;
}

So my ultimate question is, why does the line creature1->getName() function correctly on both my laptop and the schools server while in the early if statement , but only work on my local machine and fail to work on the remote server later on (near p1Attack)? 所以我的最终问题是,为什么在早期if statement ,行creature1->getName()在笔记本电脑和学校服务器上都能正常运行,但只能在本地计算机上使用,而稍后在远程服务器上无法使用(在p1Attack附近)?

If something works on one machine but not another you can be sure that you've become victim of undefined behaviour . 如果一台机器上的某物有效,但另一台机器上的不适,您可以确定您已经成为不确定行为的受害者。

And indeed, you're using dangling pointers. 实际上,您正在使用悬空指针。 Basically, it boils down to this: 基本上,可以归结为:

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;
}

To solve this you need to either store your objects where they're not subject of automatic memory management (eg on the heap) or rearrange your code to take advantage of it. 为了解决这个问题,您需要将对象存储在不受自动内存管理约束的对象上(例如在堆上),或者重新排列代码以利用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM