两个需要互相引用的对象。坏主意?

时间:2016-02-16 05:55:00

标签: c++ dependencies friend

我正在用C ++开发一个非常小而简单的游戏引擎。我有一个Creature类和一个Weapon类。生物需要知道它拥有什么武器,每个武器需要知道拥有它的生物。我喜欢武器知道生物有什么的主要原因是为了防止它摧毁它自己的生物(当武器攻击时,会检测到它碰撞的所有生物并杀死它们,除了拥有武器的生物)。

这是(简化的)Creature类的样子:

class Creature {
    private:
    Weapon* weapon_;
    public:
    void SetWeapon(Weapon* w){
        // do some other stuff (e.g. remove Weapon from any other Creatures)
        weapon_ = w;
        w->creature_ = this;
    }
}

这是(简化的)武器类的样子:

class Weapon{
    friend class Creature; // Creature needs access to creature_ pointer
    private:
    creature_;
}

正如你所看到的,我已经让Creature成为了Weapon的朋友类,因此Creature的setWeapon()方法可以适当地设置私有的creature_指针。

我的具体问题:

  1. 我听说两个对象互相引用是糟糕的设计。但在我的情况下,我怎么会不这样做呢?我真的"感觉"每个生物应该知道它拥有什么武器,每个武器都应该知道生物有什么(这样它不会伤害那个生物)。有没有办法实现我想要的东西没有这两个类相互引用?我在我的游戏引擎中一遍又一遍地遇到了这个相同的问题,包括地图/实体,库存/物品等......似乎每当我有一个" Container" class和" Item"类,这个引用问题再次出现。我想把项目的责任只放在其中一个类中,但是我希望BOTH类能够彼此了解(即我希望生物知道它的武器和武器来了解它的生物)。是否有任何方法可以实现这一点而不必让两个项目相互引用?

  2. 这种设计有时是必要的吗?或者是否有一种通用的方法可以始终避免它实现相同类型的功能?

  3. 如果真正需要这种设计来实现这种类型的功能,那么使用朋友类正确处理它的方式是什么?

  4. 提前非常感谢你。我非常有兴趣学习是否有办法实现这种类型的功能而不需要相互引用对象。

3 个答案:

答案 0 :(得分:1)

这种问题时有发生,并通过以下技术解决:

class Creature {
public:
    void SetWeapon(Weapon* w) {
        weapon_ = w;
        weapon_->SetCreature(this);
    }
private:
    Weapon* weapon_;
};

class Weapon {
public:
    void SetCreature(Creature* _creature) {
        m_owner = _creature;
    }
private:
    Creature* m_owner;
};

关于你的广泛问题 - 如果你经常在同一个项目中遇到这类问题,我建议你重新考虑你的设计解决方案。
例如,你关于武器知识它的生物的命题是违反直觉的,感觉不对。所以从这个假设开始,我相信你最终会得到更好的设计,你的武器对于它们的拥有者一无所知(就像在现实生活中一样!)。

答案 1 :(得分:0)

  1. 你听错了。以这种方式使用引用对象不是一个好的编程习惯,但是再次使用goto被一些人认为是一种糟糕的方法。对于替代解决方案,请参见下文。

  2. 可以使用此设计,因为有时我们也需要goto循环。不喜欢许多方法。

  3. 替代解决方案: 根据您的要求,我可以建议一种替代方法,希望这会有所帮助。您可以创建struct来容纳玩家对象和武器对象,而不是在各自的类中相互引用。这样,根据需要操作和更改将更容易。即玩家可以拥有许多武器(在这种情况下你可以在struct中创建一个阵列)。每个玩家都有一个与之相关的武器实例。

答案 2 :(得分:0)

让对象来回传递是很常见的。一个常见的例子是指向父级的指针。你的概念非常合理。只需确保你有你的析构函数,以便清除对象指针。

~Weapon()中,清除Creature指向武器的指针,反之亦然。