【问题标题】:Circular dependency in two classes - code doesn't compile [closed]两个类中的循环依赖 - 代码无法编译 [关闭]
【发布时间】:2012-10-09 01:03:18
【问题描述】:

所以,我正在尝试用 C++ 开发一个非常简单的游戏(我一直使用 C#,我只是在深入研究 C++),并且想复制我使用的简单(尽管设计不佳)组件实体系统C#。

此代码不能使用带有 C++11 标准的 g++ 编译。

我该如何解决?我是否必须更改设计,或者是否有解决方法?


格式良好的馅饼:http://pastie.org/5078993


Eclipse 错误日志

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_ */

组件.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(); }

【问题讨论】:

  • 您是否尝试过在Entity.h 中前向声明Component 类,而不是像在Component.h 中使用Entity 那样包含头文件?
  • @JoachimPileborg 刚试过。同样的问题
  • 从错误消息中还不清楚哪个文件正在编译,但我只是尝试使用 g++ 4.3.3 和 MSVC++ 9 编译 Component.cpp 和 Entity.cpp(在注释掉Entity::~Entity()Entity::update() 使用 auto C++11-ism) 并且他们都愉快地编译它而没有错误。所以我确定错误不是来自这些文件。
  • 在编译每个 .cpp 文件时应该使用 -c,然后在单独的步骤中将它们链接在一起,或者应该省略 -c 并在单个命令行上指定所有 .cpp 文件。
  • @j_random_hacker 我想通了! Eclipse 报告的“错误”实际上是代码分析问题。令人惊讶的是,开发人员认为默认情况下将它们与编译器错误放在同一类别中是个好主意。幸运的是,我能够将它们自定义为仅显示为警告。 :) 另外,您能否发布一个简单的答案以便我接受?

标签: c++ g++ dependencies header-files circular-dependency


【解决方案1】:

您必须将Entity.h 包含在component.cpp

【讨论】:

  • 我试过这样做,但产生了同样的错误。
【解决方案2】:

问题是否可能不是循环包含,而是代码本身?例如:“无法解析方法'更新'”给你一个提示,你必须定义Component::update方法,与Component::init方法相同,因为它们不是纯虚拟的。请先尝试删除此错误,然后查看是否有帮助

更新: 所以...我测试了你的代码。不是用 eclipse,而是用 Visual Studio 2008。我用“正常”for (std::vector&lt;Component*&gt;::iterator... 替换了for (auto... 的东西,因为这在这个版本的 VS 中不可用。正如我可以说的,没有循环依赖,但您忘记了 Entity.h 文件中的#include &lt;vector&gt;。并且缺少那些虚拟函数的定义,但你说,你已经添加了它们,所以忘记了;)

【讨论】:

  • 我可以通过注释掉这些方法来消除这个错误。但是“无效参数”错误仍然存​​在
【解决方案3】:

事实证明,其实不存在循环依赖问题,代码编译链接正常。 “错误”实际上只是 Eclipse 过分热心的代码分析报告——在命令行上分别编译每个 .cpp 文件

g++ -c thatfile.cpp

不会产生编译错误,并且可以一次性编译和链接

g++ Entity.cpp Component.cpp

产生一个工作可执行文件。

【讨论】:

  • 再次感谢!我还在 Eclipse CDT BugZilla 页面上提交了错误/建议报告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 2021-08-15
相关资源
最近更新 更多