将对象分配给指针c ++时出错

时间:2014-04-12 06:09:51

标签: c++ pointers

我和我的朋友正在用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是不起作用的。

3 个答案:

答案 0 :(得分:0)

class StartMap : public Map;

在语法上是不正确的。你需要

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

您需要对JungleMapRiverMap进行类似的更改。

答案 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时,他们立即知道它是类名还是变量名。