C ++,两个有共同需求的类

时间:2012-06-11 11:15:42

标签: c++ circular-dependency

我已经将科学的仿真平台从Java转换为C ++。我试图尽可能地保持设计与之前的实现相同。在java中,由于后期绑定,循环依赖项在运行时被解析。然而,循环依赖在C ++中造成了一团糟。

  1. 是否有自动化工具可以分析和列出循环包含和参考? (Visual Studio 2010仅发出大量无意义错误。)

  2. 我试图尽可能使用前向引用。然而,在某些情况下,两个类都需要另一个类的功能(即调用方法,这使得无法使用前向引用)。这些需求存在于Logic中,如果我从根本上改变设计,它们将不再代表真实世界的交互。

    我们怎样才能实现两个需要彼此方法和状态的类?是否可以在C ++中实现它们?

  3. 示例:

    • 示例1:我有一个名为“World”的类,它创建“Agent”类型的对象。代理需要调用World方法来获取其环境的信息。 World还需要遍历代理并执行其“运行”方法并获取其状态(状态更新可能会反向完成以解决问题的这一部分而不是运行方法)。
    • 示例2:代理商创建其“意图”的集合。每个代理需要迭代其意图并运行/更新/读取意图状态。意图还需要通过Agent获取有关环境的信息(如果直接通过“World”完成,它将再次创建复杂的圈子)以及代理本身的信息。

    下图显示了一个类的子集,以及它们的一些方法和属性:

    sub-set of classes, and some of their methods and properties

2 个答案:

答案 0 :(得分:17)

我没有看到前方声明对你不起作用。看起来你需要这样的东西:

World.h:

#ifndef World_h
#define World_h

class Agent;

class World
{
    World();
    void AddAgent(Agent* agent) { agents.push_back(agent); }
    void RunAgents();
private:
    std::vector<Agent*> agents;
};

#endif

Agent.h:

#ifndef Agent_h
#define Agent_h

class World;
class Intention;

class Agent
{
    Agent(World& world_): world(world_) { world.AddAgent(this); }
    status_t Run();
private:
    World& world;
    std::vector<Intention*> intentions;
};

#endif

World.cc:

#include "World.h"
#include "Agent.h"

void World::RunAgents()
{
    for(std::vector<Agent*>::iterator i = agents.begin(); i != agents.end; ++i)
    {
        Agent& agent(**i);
        status_t stat = agent.Run();
        // do something with stat.
    }
}

// ...

Agent.cc:

#include "Agent.h"
#include "World.h"
#include "Intention.h"

// ...

答案 1 :(得分:3)

可以只使用前向声明来解决问题,但是你可能没有将实现与类的声明分开。

如果需要从类中调用方法,则需要完整类型,这就是您需要包含该文件的原因。您可以将文件包含在cpp(实现文件)中,而不必担心循环依赖性。