C ++使用A类作为B类成员函数的参数,B类是A类的成员

时间:2014-07-11 23:24:25

标签: c++ class circular-dependency

基本上,我在两个不同的头文件下有两个类。 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。虽然有时候我只是需要用稍微不同的方式来理解这些内容。

感谢您的时间和帮助。

1 个答案:

答案 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的大小,前向声明就足够了,所以没有交叉包含。