2015-11-07 59 views
0

我很努力地理解我在這裏遇到的問題。這是學校課程的一項任務。我在筆記本電腦上編寫我的代碼,並在學校的服務器上編譯/測試/提交。C++中的基類和派生類的範圍

我目前在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)如果他們每個創建的那些各自的特點。在我的本地機器上,代碼運行正確,並按照它應該用圓括號拼寫出來。

我的生物類和.setStats()從creature.cpp的例子:

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)?

+3

'生物*生物1,*生物2; //創建對象'。不完全是。指針創建?是。他們有效嗎?沒有創建對象?號碼 –

+0

你應該爲這兩個生物分配記憶 – MORTAL

+1

我覺得你正在做一些你沒有顯示的東西。這根本不應該運行,因爲正如其他評論所說,生物2是無效的。所以我想你會剪掉實際創建這樣一個對象的部分。無論如何,這聽起來像你可能會遇到未定義的行爲。一個不涉及任何外部資源但不嘗試任何未定義的程序應該在各處編譯相同的內容。 – 2015-11-07 05:24:12

回答

1

如果在一臺機器上有效但不是另一臺機器,則可以確定您已成爲未定義行爲的受害者

事實上,你使用的是懸掛指針。基本上,它歸結爲:

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

爲了解決這個問題,你需要可以存儲你的對象,他們是不受自動內存管理(例如,在堆)或重新安排你的代碼,以利用它的優勢。