我写了一个文件分析器的游戏,我写很容易让自己改变了游戏的各个方面(之类的字符/台/碰撞数据)。例如,我可能有一个字符类是这样的:

class Character
{
public:
    int x, y; // Character's location
    Character* teammate;
}

设置我解析器从文件中读入与语法类似于C ++

的数据结构
Character Sidekick
{
    X = 12
    Y = 0
}

Character AwesomeDude
{
    X = 10
    Y = 50
    Teammate = Sidekick
}

这将产生两个数据结构,并把它们放在一个map<std::string, Character*>,其中关键字符串是什么名字,我把它(在这种情况下的Sidekick和AwesomeDude)。当我的解析器看到一个指向类,像队友指针,它是足够聪明来查找地图来获取指向该数据结构。问题是,我不能宣布搭档的队友是AwesomeDude,因为它没有被放入字符映射表呢。

我试图找到解决它的最好方法,这样我可以有尚未被添加到我的地图数据结构的参考对象。我能想到的是:(a)加入到转发申报数据结构或(b)已通过文件读取的解析器两次,一次填充指向空数据结构图和第二次的能力,这两个最简单的解决方案经过并在填充它们。

用(A)的问题是,我还可以决定一个类调用哪个构造函数,如果我向前声明的东西我得有构造从数据的其余部分,这可能会产生混淆分开。与(B)的问题是,我可能要申报的Sidekick和AwesomeDude在自己的文件。我必须让我的解析器能够采取的文件列表,在一个时间阅读,而不是只有一个(这是不是如此糟糕,我猜,虽然有时候我可能希望得到的文件从一个阅读列表文件)。 (B)还具有不能够使用以后在构造函数本身声明的数据结构的缺点,但我不认为这是一个巨大的交易。

哪种方式听起来像一个更好的办法?有没有我都没有想到的第三种选择?好像就必须有一些巧妙的解决了这个用指针引用或结合或东西...: - /我想这是有些主观的基础上有什么特点,我想给自己,但任何投入是值得欢迎的。

有帮助吗?

解决方案

当遇到的基准的第一次,简单地将其存储作为参考。然后,你可以把文字,或参考,或什么的“需要以后解决的引用”列表。

这是

当文件完成后,通过那些有引用和运行解决这些问题。

其他提示

好了,你问的第三个选项。您不必使用XML,但如果你按照下面的结构,这将是非常简单的使用SAX解析器来构建你的数据结构。

在任何速率,而不是引用队友,每个字符引用一个团队(团队蓝在这种情况下)。这会脱钩循环引用问题。只要确保你的人物之前列出的团队。

<team>Blue</team>

<character>
    <name>Sidekick</name>
    <X>12</X>
    <Y>0</Y>
    <teamref>Blue</teamref>
</character>

<character>
    <name>Sidekick</name>
    <X>10</X>
    <Y>50</Y>
    <teamref>Blue</teamref>
</character>

个人而言,我用b去)。分割你的代码解析器和验证类,在相同的数据结构两种操作。解析器将读取并解析文件,填充数据结构和存储任何对象引用作为其文本名称,留在你的结构真正的空指针现在。

当你完成加载文件时,使用Validator类验证并解决任何引用,在“真正的”指针填充。您将要考虑如何组织你的数据,以使这些查找很好,速度很快。

威尔说正是我正要写出来。只要保持一个列表,或与尚未解决的引用的东西。

不要忘记抛出一个错误,如果有未解决的参考,一旦你读完该文件= P

而不是存储在地图字符对象,存储用于字符的代理。所述代理将包含比指针的实际字符对象被加载的对象时。类型字符::队友会变成这个代理类型。当你是不是已经在你的地图参考阅读,您创建一个代理,并使用代理服务器。当加载,你已经在地图上的空白代理的角色,你的新装载的字符填充它。您可能还需要添加一个计数器来跟踪你有多少空代理在地图上,让你知道当所有引用的字符都被载入。

间接的另一层....它总是使编程更容易和更慢。

一种选择是扭转的义务。地图在参考填充负责

template<T> class SymbolMap // I never could rememeber C++ template syntax
{
   ...

   /// fill in target with thing name
   /// if no name yet, add it to the list of thing that will be name
   void Set(T& target, std::string name);

   /// define name as target
   /// go back and fill in anything that needs to be name
   void Define(T target, std::string name);

   /// make sure everything is resolved
   ~SymbolMap()
}

这将不会与值/移动语义很好地相互作用但我怀疑不多意愿。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top