Подтвердить что ты не робот

С++, два класса с взаимными потребностями

Я преобразовал платформу научного моделирования из Java в С++. Я попытался сохранить дизайн как можно больше, как и в предыдущей реализации. В java из-за позднего связывания циклические зависимости разрешаются во время выполнения. Однако круговые зависимости создали адский беспорядок на С++.

  • Есть ли автоматизированный инструмент, который анализирует и перечисляет круговые включения и ссылки? (Visual Studio 2010 выпускает огромный список ошибок бессмысленности).

  • Я старался использовать прямые ссылки везде, где это возможно. Однако в некоторых случаях оба класса нуждаются в функциональности другого класса (т.е. Вызов методов, которые делают невозможным использование прямой ссылки). Эти потребности существуют в логике, и если я радикально изменил дизайн, они больше не будут представлять взаимодействия реального мира.

    Как мы можем реализовать два класса, которым нужны друг другу методы и статус? Возможно ли реализовать их на С++?

<сильные > Примеры:

  • Пример 1: У меня есть класс под названием "Мир", который создает объекты типа "Агент". Чтобы получить информацию о своей среде, агенту необходимо вызвать методы World. World также необходимо выполнить итерацию через агентов и выполнить их метод "запуска" и получить их статус (обновления состояния могут быть сделаны обратными, чтобы решить этот раздел проблемы, но не метод запуска).
  • Пример 2: Агенты создают коллекцию своих "Намерений". Каждому Агенту необходимо выполнить итерацию по своим намерениям и запустить/обновить/прочитать статус намерения. Намерения также должны получить информацию об окружающей среде через Агента (если сделать непосредственно через "Мир", он снова создаст сложные круги), а также информацию о самом Агенте.

Ниже диаграммы показан подмножество классов, а также некоторые их методы и свойства:

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

4b9b3361

Ответ 1

Я не вижу, как декларации не работают для вас. Похоже, вам нужно что-то вроде:

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

Вы можете решить проблему только с объявлениями только вперед, но вы, вероятно, не отделили реализацию от объявления класса.

Если вам нужно вызвать методы из класса, необходим полный тип, поэтому вам необходимо включить этот файл. Вы можете включить файл в файл cpp (файл реализации), не беспокоясь о круговых зависимостях.