基本上,我在两个不同的头文件下有两个类。 ToolBar
和NewMenu
(我会使用实际的类名来更好地理解)这两个类都在namespace map
下。现在我在类NewMenu
内声明了类ToolBar
。但是,我在NewMenu
,(HandleEvents(..., ToolBar& toolBar)
)中有一个成员函数,它处理事件,但是将类ToolBar
作为参数,以便根据事件传递和编辑某些信息那个会发生。但是,这似乎导致循环依赖。
所以基本上......我这样开始......
// ToolBar.h
#include "NewMenu.h"
namespace map
{
class ToolBar
{
private:
NewMenu myNewMenu;
public:
/* ... */
}
} // namespace map
//////////////////////////
// NewMenu.h
#include "ToolBar.h"
namespace map
{
class NewMenu
{
private:
/* ... */
public:
void HandleEvents(ToolBar& toolBar)
{
/* ... */
//Use ToolBar function
toolBar.tileMap.Create();
/* ... */
}
/* ... */
}
} // namespace map
但是,这会导致循环依赖。所以我接着做了一些研究试图解决这个问题并得到类似的东西......
// ToolBar.h
#include "NewMenu.h"
namespace map
{
class ToolBar
{
private:
NewMenu myNewMenu;
public:
/* ... */
}
} // namespace map
//////////////////////////
// NewMenu.h
//#include "ToolBar.h"
namespace map
{
class ToolBar; //(I presume) to make a temporary reference to class ToolBar.
class NewMenu
{
private:
/* ... */
public:
void HandleEvents(ToolBar& toolBar)
{
/* ... */
//Use ToolBar function
toolBar.tileMap.Create(); //Error: incomplete type is not allowed
/* ... */
}
/* ... */
}
} // namespace map
我不是100%肯定,但基于我收集的内容,这应该基本上解决它(?),但是,现在我在HandleEvents()
函数中出现错误"错误:不允许不完整的类型。"所以我的问题是,我出了什么问题以及如何解决这种循环依赖?
(旁注:我得到了一些我的研究here。虽然有时候我只是需要用稍微不同的方式来理解这些内容。
感谢您的时间和帮助。
答案 0 :(得分:3)
主要问题是如果前向声明不足以解决它,则不能具有循环依赖性。由于您不仅声明handleEvents
,而且甚至实现它,因此编译器必须知道ToolBar
的大小。如果您在cpp文件中移动实现,则问题将消失。
如果B的定义需要知道A的大小而B的定义需要知道A的大小,那么你就不走运了。
问题的最佳解决方案,因为ToolBar
包含NewMenu
,其解决方法类似于以下方式:
// ToolBar.h
#include "NewMenu.h" // needed because you need to know the size of NewMenu
class ToolBar {
NewMenu menu;
..
}
// NewMenu.h
class ToolBar;
class NewMenu {
void HandleEvents(const ToolBar& toolBar); // <- look, it's a reference, no need to know the size of ToolBar
}
// NewMenu.cpp
#include "NewMenu.h"
#include "ToolBar.h" // you can safely include it here
NewMenu::handleEvent(const ToolBar& toolBar) {
toolBar.whatever();
}
通过这种方式问题得以解决,因为NewMenu.h
不需要知道ToolBar
的大小,前向声明就足够了,所以没有交叉包含。