基本上,我在两个不同的头文件下有两个类。 ToolBarNewMenu(为了更好的理解,我将使用实际的类名)这两个类都在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。尽管有时我只需要一些显示出稍微不同的理解方式的东西)

感谢您的时间和帮助。

最佳答案

主要问题是,如果前向声明不足以解决它,则不能具有循环依赖关系。由于您不仅要声明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的大小,前向声明就足够了,因此没有交叉包含。

关于c++ - C++使用类A作为类B成员函数的参数,而类B是类A的成员,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24708021/

10-16 17:00