2014-04-12 199 views
0

錯誤我和我的朋友正在用C++編寫基於文本的遊戲,以獲得更多樂趣,並學習更多。我一直在嘗試使用指向類的指針,但沒有運氣,並且發生了一些錯誤,這些錯誤對我來說完全沒有意義,並且希望有人能夠幫助我。將對象分配給指針C++

代碼:

//Map.h 
    #include "Player.h" 

    class Map 
    { 
     //Virtual functions 
    }; 

    class StartMap : public Map 
    { 
     //Code 
    }Start; 

    class JungleMap : public Map 
    { 
     //Code 
    }Jungle; 

    class RiverMap : public Map 
    { 
     //Code 
    }River; 


    //Player.h 
    #ifndef MAP_H 
    #define MAP_H 
    #endif 

    class Player 
    { 
     private: 
      Map *PlayerMap; 
      //Other variables 
     public: 
      void Initialize() 
      { 
       //Initialize variables 
       PlayerMap = &Start; //This is where the error occurs, says there's a 
            //<error-type>*Player::PlayerMap. Tried putting 
            //this->PlayerMap = &Start, didn't help 
            //There's no error when I make the pointer 
      } 

      //Bunch of other functions 
    }Player; 

好吧,這是我的代碼,因爲我決定添加.cpp文件:

//Command.h 
    class Command 
    { 
    private: 
    string GameCommand; 

    void Trim(); 

    public: 
    Command (string command) {GameCommand = command;} 
    Command() {} 
    void operator = (string command) {GameCommand = command;} 

    void ReadCommand(); 

    string Print(); 
    } 


    //Command.cpp 
    #include <iostream> 
    #include <string> 
    #include "Command.h" 
    #include "Parameter.h" 

    using namespace std; 

    void Command::Trim() 
     { 
     int LeadingPos = 0, MidCount = 0, TrailingPos = GameCommand.length()-1, Size = 0; 
     string TempCommand = ""; 
     while (GameCommand[LeadingPos] == ' '){LeadingPos += 1;} 
     while (GameCommand[TrailingPos] == ' '){TrailingPos -= 1;} 
     Size = ((TrailingPos+1)-LeadingPos); 
     for (int loops = 0; loops < Size; loops++) 
     { 
      if (MidCount > 0 && GameCommand[LeadingPos] == ' ') 
      { 
       LeadingPos += 1; 
      } 
      else 
      { 
       if (GameCommand[LeadingPos] == ' ') 
       { 
        MidCount += 1; 
       } 
       TempCommand += GameCommand[LeadingPos]; 
       LeadingPos += 1; 
      } 
     } 
     GameCommand = TempCommand; 
    } 

    void Command::ReadCommand() 
    { 
     Trim(); 
     string Parameter; 
     if (GameCommand.substr(0,3) == "go ") 
     { 
      Parameter = GameCommand.substr(3,string::npos); 
      CommandParameter.Go(Parameter); 
     } 
     else if (GameCommand.substr(0,4) == "dig ") 
     { 
      Parameter = GameCommand.substr(4,string::npos); 
      CommandParameter.Dig(Parameter); 
     } 
     else if (GameCommand.substr(0,4) == "eat ") 
     { 
      Parameter = GameCommand.substr(4,string::npos); 
      CommandParameter.Eat(Parameter); 
     } 
     else if (GameCommand.substr(0,4) == "exit" || GameCommand.substr(0,4) == "quit") 
     { 
      exit(0); 
     } 
     else if (GameCommand.substr(0,4) == "use ") 
     { 
      Parameter = GameCommand.substr(4,string::npos); 
      CommandParameter.Use(Parameter); 
     } 
     else if (GameCommand.substr(0,5) == "drop ") 
     { 
      Parameter = GameCommand.substr(5,string::npos); 
      CommandParameter.Drop(Parameter); 
     } 
     else if (GameCommand.substr(0,5) == "grab " || GameCommand.substr(0,5) == "take ") 
     { 
      Parameter = GameCommand.substr(5,string::npos); 
      CommandParameter.Pickup(Parameter); 
     } 
     else if (GameCommand.substr(0,5) == "help ") 
     { 
      Parameter = GameCommand.substr(5,string::npos); 
      CommandParameter.Help(Parameter); 
     } 
     else if (GameCommand.substr(0,5) == "look ") 
     { 
      Parameter = GameCommand.substr(5,string::npos); 
      CommandParameter.Look(Parameter); 
     } 
     else if (GameCommand.substr(0,5) == "sleep") 
     { 
      CommandParameter.Sleep(); 
     } 
     else if (GameCommand.substr(0,6) == "check ") 
     { 
      Parameter = GameCommand.substr(6,string::npos); 
      CommandParameter.Check(Parameter); 
     } 
     else if (GameCommand.substr(0,6) == "climb ") 
     { 
      Parameter = GameCommand.substr(6,string::npos); 
      CommandParameter.Climb(Parameter); 
     } 
     else if (GameCommand.substr(0,6) == "throw ") 
     { 
      Parameter = GameCommand.substr(6,string::npos); 
      CommandParameter.Throw(Parameter); 
     } 
     else if (GameCommand.substr(0,7) == "attack ") 
     { 
      Parameter = GameCommand.substr(7,string::npos); 
      CommandParameter.Attack(Parameter); 
     } 
     else if (GameCommand.substr(0,7) == "search ") 
     { 
      Parameter = GameCommand.substr(7,string::npos); 
      CommandParameter.Search(Parameter); 
     } 
     else 
     { 
      cout << "Not a valid command.\n"; 
     } 
    } 

    string Print() 
    { 
     return GameCommand; 
    } 

字符串GameCommand就是不工作。

回答

0
class StartMap : public Map; 

在語法上不正確。您需要

class StartMap : public Map 
{ 
    // Details of class 
} Start; 

你需要作出類似更改JungleMapRiverMap

+0

雖然合法,但這是非常糟糕的風格。類定義應該獨立於該類的對象的實例化。 –

+0

對於'Player'來說,它也不是合法的,它在代碼中既是類型又是變量名。 – WhozCraig

0

我注意到的是每個繼承之後的聲明分號第一件事.. class XXXXX : public Map; < - 即分號不應該有..

在初始化函數,我敢肯定你意思是PlayerMap = new StartMap();

你需要一個析構函數來刪除它和一個副本,移動構造函數以及賦值操作符以便分配,移動或複製類。

你可以按照這個方法,使類符合RAII:What is the copy-and-swap idiom?

+0

將'PlayerMap = &Start;'更改爲'PlayerMap = new StartMap();'仍然給出錯誤 – Shadow

+0

你得到這個的原因是因爲你繼續把這些類型放在類之後..它應該是'class Player {... 。};'not'class Player {...} Player;'因爲你這樣做了,所以你有一個名爲Player的Player實例,以及一個名爲Player的類。 – Brandon

0

有許多與你的代碼佈局的問題。

這並不做任何事情:

//Player.h 
#ifndef MAP_H 
#define MAP_H 
#endif 

我猜你正在嘗試做一個包括後衛。正確的佈局是:

#ifndef PLAYER_H 
#define PLAYER_H 

// all your code for the header file goes here 
class Player 
{ 
// .... 
}; 

#endif // no more code after this line 

下一個問題是,Player.h應包括Map.h,而不是周圍的其他方式。想象一下你是編譯器。您正在處理Player.h。你最多可以達到Map *PlayerMap;。但是你不知道Map是因爲你還沒有看到Map.h呢。所以你必須給出一個錯誤並停止編譯。

Map.h地圖的定義應該是這樣的:

class StartMap : public Map 
{ 
    //Code 
}; 

Start;您對到底是風格差。如果兩個不同的.cpp文件包含Map.h,將會導致未定義的行爲,因爲會有兩個具有相同名稱的不同全局變量。

移至void Map::Initialize()函數。你應該使用構造函數進行初始化。無論哪種方式,我的建議是,你不要在Player.h執行此。相反,只是有void Initialize();,然後在Map.cpp你可以有:

// the global variables 
StartMap start_map; 
JungleMap jungle_map; 

void Map::Initialize() 
{ 
    player_map = &start_map; 
} 

它使用了類比變量不同的命名約定是一個好主意。因此,例如,當有人看到StartMap時,他們立即知道它是類名還是變量名。

+0

我把'#endif'放在頭文件的末尾,就像你說的那樣。 Map.h必須'#include「Player.h」'因爲Map類通過調用Player中包含的函數來處理移動播放器。我試圖實現的是,而不是嵌套如果是輸入的命令,只是去'Player :: PlayerMap-> GoSouth()' – Shadow

+0

否則它的'if(Player.GetMap()==「開始」){ Start.GoSouth();}'每個地圖(N,S,E,W)有4個if,並且會有很多地圖。 – Shadow

+0

「Map類通過調用播放器中包含的函數處理移動播放器。」 - 將該代碼放入'Map.cpp'中。 'Map.cpp'可以包含'Player.h'',但'Map.h'不應該。 –