2014-04-12 157 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'不应该。 –