我和我的朋友正在用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 :(得分:0)
class StartMap : public Map;
在语法上是不正确的。你需要
class StartMap : public Map
{
// Details of class
} Start;
您需要对JungleMap
和RiverMap
进行类似的更改。
答案 1 :(得分:0)
我注意到的第一件事是每个继承声明后的分号。
class XXXXX : public Map;
&lt; - 那个分号不应该在那里..
在初始化函数中,我很确定你的意思是PlayerMap = new StartMap();
你需要一个析构函数来删除它和一个副本,移动构造函数以及赋值运算符,以便分配,移动或复制类。
您可以按照此操作使该课程符合RAII:What is the copy-and-swap idiom?
答案 2 :(得分: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
时,他们立即知道它是类名还是变量名。