C++, two classes with mutual needs

拟墨画扇 提交于 2019-11-27 01:28:51

问题


I have converted a scientific simulation platform from Java into C++. I have tried to keep the design as much as possible the same as previous implementation. In java because of the late binding, circular dependencies are resolved at the run time. However, circular dependencies have created a hell of a mess in C++.

  1. Is there an automated tool which analyses and lists the circular includes and references? (Visual Studio 2010 only issues a huge list of nonsense errors).

  2. I have tried to use forward references wherever possible. However in some occasions both classes need functionality of the other class (i.e. call to methods which makes it impossible to use forward reference). These needs exist in Logic and if I radically change the design they will no more represent real world interactions.

    How could we implement two classes which need each other's methods and status? Is it possible to implement them in C++?

Examples:

  • Example 1: I have a class called "World" which creates Objects of the type "Agent". Agent needs to call World methods to get information of its environment. World also needs to iterate through Agents and execute their "run" method and get their status (status updates may possibly be done reverse to solve this section of the problem but not the run method).
  • Example 2: Agents create a collection of their "Intentions". Each Agent needs to iterate through its intentions and run/update/read intention status. Intentions also need to get information about the environment through Agent (if done directly through "World" it will create complex circles again) and also info of the Agent itself.

Below diagram shows a sub-set of classes, and some of their methods and properties:


回答1:


I'm not seeing how forward declarations are not working for you. It looks like you need something like:

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"

// ...



回答2:


You can solve the problem with only forward declarations, but you probably didn't separate the implementation from the declaration of the class.

If you need to call methods from the class, a full type is needed, which is why you need to include the file. You can include the file in a cpp (implementation file) without worrying about circular dependencies.



来源:https://stackoverflow.com/questions/10979031/c-two-classes-with-mutual-needs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!