Круговая зависимость в двух классах — код не компилируется

Итак, я пытаюсь разработать действительно простую игру на C ++ (я всегда использовал C #, я просто погружаюсь в C ++) и хотел воспроизвести мою простую (хотя и плохо разработанную) систему компонент-сущностей, которую я сделал с C #.

Этот код не компилируется с использованием g ++ со стандартом C ++ 11.

Как я могу это исправить? Нужно ли менять дизайн или есть обходной путь?


Хорошо отформатированный пирожок: http://pastie.org/5078993


Eclipse error log

Description Resource    Path    Location    Type
Invalid arguments '
Candidates are:
void push_back(Component * const &)
'   Entity.cpp  /TestEntity line 15 Semantic Error
Invalid arguments '
Candidates are:
__gnu_cxx::__normal_iterator<Component * *,std::vector<Component *,std::allocator<Component *>>> erase(__gnu_cxx::__normal_iterator<Component * *,std::vector<Component *,std::allocator<Component *>>>)
__gnu_cxx::__normal_iterator<Component * *,std::vector<Component *,std::allocator<Component *>>> erase(__gnu_cxx::__normal_iterator<Component * *,std::vector<Component *,std::allocator<Component *>>>, __gnu_cxx::__normal_iterator<Component * *,std::vector<Component *,std::allocator<Component *>>>)
'   Entity.cpp  /TestEntity line 19 Semantic Error
Method 'update' could not be resolved   Entity.cpp  /TestEntity line 22 Semantic Error
Invalid arguments '
Candidates are:
#0 remove(#0, #0, const #1 &)
'   Entity.cpp  /TestEntity line 19 Semantic Error

Component.h

#ifndef COMPONENT_H_
#define COMPONENT_H_

class Entity;

class Component {
private:
Entity* parentPtr;

public:
virtual void init();
virtual void update();
virtual ~Component();
void setParent(Entity* mParentPtr);
};

#endif /* COMPONENT_H_ */

Component.cpp

#include "Component.h"
void Component::setParent(Entity* mParentPtr) { parentPtr = mParentPtr; }

Entity.h

#ifndef ENTITY_H_
#define ENTITY_H_

#include "Component.h"
class Entity {
private:
std::vector<Component*> componentPtrs;

public:
~Entity();
void addComponent(Component* mComponentPtr);
void delComponent(Component* mComponentPtr);
void update();
};

#endif /* ENTITY_H_ */

Entity.cpp

#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <sstream>
#include <algorithm>

#include "Entity.h"#include "Component.h"
Entity::~Entity() {
for (auto &componentPtr : componentPtrs) delete componentPtr;
}
void Entity::addComponent(Component* mComponentPtr) {
componentPtrs.push_back(mComponentPtr);
mComponentPtr->setParent(this);
}
void Entity::delComponent(Component* mComponentPtr) {
componentPtrs.erase(remove(componentPtrs.begin(), componentPtrs.end(), mComponentPtr), componentPtrs.end());
delete mComponentPtr;
}
void Entity::update() { for (auto &componentPtr : componentPtrs) componentPtr->update(); }

0

Решение

Оказывается, что на самом деле нет проблем с циклической зависимостью, а код компилируется и связывается нормально. «Ошибка» на самом деле является просто чрезмерной отчётностью по анализу кода Eclipse — компилирует каждый файл .cpp отдельно в командной строке с помощью

g++ -c thatfile.cpp

не производит ошибок компиляции, а компиляция и компоновка за один раз

g++ Entity.cpp Component.cpp

производит рабочий исполняемый файл

1

Другие решения

Вы должны включить Entity.h в component.cpp

0

Возможно ли, что проблема не в циклических включениях, а в самом коде? Например: «Метод« обновление »не может быть разрешен» дает вам подсказку, что вы должны определить Component::update метод, то же самое с Component::initметод, поскольку они не являются чисто виртуальными. Попробуйте сначала удалить эти ошибки, а затем посмотрите, поможет ли это

Обновить:
Итак … я проверил твой код. Не с затмением, а с Visual Studio 2008. Я заменил for (auto... материал с «нормальным» for (std::vector<Component*>::iterator..., поскольку это не было доступно в этой версии VS. Как я могу сказать, нет круговой зависимости, но вы забыли #include <vector> в вашем файле Entity.h. И определения этих вирусных функций отсутствовали, но вы сказали, что уже добавили их, так что забудьте об этом;)

0
По вопросам рекламы [email protected]