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

C++ C++;使用类A作为类B的成员函数的参数,而类B是类A的成员,c++,class,circular-dependency,C++,Class,Circular Dependency,基本上,我在两个不同的头文件下有两个类工具栏和新建菜单(为了更好地理解,我将使用实际的类名)这两个类都在名称空间映射下。现在我在类工具栏中声明了类NewMenu。但是,我在NewMenu,(HandleEvents(…,ToolBar&ToolBar))中有一个成员函数,它处理事件,但将类ToolBar作为参数,以便根据发生的事件传递和编辑某些信息。然而,这似乎会导致循环依赖 所以基本上。。。我是这样开始的 // ToolBar.h #include "NewMenu.h" namespace

基本上,我在两个不同的头文件下有两个类<代码>工具栏和
新建菜单
(为了更好地理解,我将使用实际的类名)这两个类都在
名称空间映射
下。现在我在类
工具栏中声明了类
NewMenu
。但是,我在
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
但是,这会导致循环依赖。然后我做了一些研究试图解决这个问题,得到了这样的结果

// 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()
函数中得到一个错误,说“错误:不允许不完整类型”。所以我的问题是,我出了什么错,我如何修复这个循环依赖关系

(旁注:我做了一些研究。尽管有时我只是需要用一种稍微不同的方式来理解事情)


感谢您的时间和帮助。

主要的问题是,如果转发声明不足以解决循环依赖性问题,您就无法获得循环依赖性。由于您不仅要声明
handleEvents
,而且还要实现它,因此编译器必须知道
工具栏的大小。如果在cpp文件中移动实现,那么问题就会消失

如果B的定义需要知道A的大小,B的定义需要知道A的大小,那么你就不走运了

由于
工具栏
包含一个
新菜单
,因此最好的解决方案是以类似于以下的方式解决此问题:

// 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();
}
//ToolBar.h
#包括“NewMenu.h”//needed,因为您需要知道NewMenu的大小
类工具栏{
新菜单;
..
}
//新菜单
类工具栏;
类新菜单{

void HandleEvents(常量工具栏和工具栏);//主要的问题是,如果正向声明不足以解决循环依赖性问题,那么它就不可能存在循环依赖性。因为你不仅仅是在声明
handleEvents
,甚至是在实现它,编译器必须知道
工具栏的大小。如果在cpp文件中移动实现,那么问题就会消失

如果B的定义需要知道A的大小,B的定义需要知道A的大小,那么你就不走运了

由于
工具栏
包含一个
新菜单
,因此最好的解决方案是以类似于以下的方式解决此问题:

// 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();
}
//ToolBar.h
#包括“NewMenu.h”//needed,因为您需要知道NewMenu的大小
类工具栏{
新菜单;
..
}
//新菜单
类工具栏;
类新菜单{

void HandleEvents(常量工具栏和工具栏);//主要的问题是,如果正向声明不足以解决循环依赖性问题,那么它就不可能存在循环依赖性。因为你不仅仅是在声明
handleEvents
,甚至是在实现它,编译器必须知道
工具栏的大小。如果在cpp文件中移动实现,那么问题就会消失

如果B的定义需要知道A的大小,B的定义需要知道A的大小,那么你就不走运了

由于
工具栏
包含一个
新菜单
,因此最好的解决方案是以类似于以下的方式解决此问题:

// 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();
}
//ToolBar.h
#包括“NewMenu.h”//needed,因为您需要知道NewMenu的大小
类工具栏{
新菜单;
..
}
//新菜单
类工具栏;
类新菜单{

void HandleEvents(常量工具栏和工具栏);//主要的问题是,如果正向声明不足以解决循环依赖性问题,那么它就不可能存在循环依赖性。因为你不仅仅是在声明
handleEvents
,甚至是在实现它,编译器必须知道
工具栏的大小。如果在cpp文件中移动实现,那么问题就会消失

如果B的定义需要知道A的大小,B的定义需要知道A的大小,那么你就不走运了

由于
工具栏
包含一个
新菜单
,因此最好的解决方案是以类似于以下的方式解决此问题:

// 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();
}
//ToolBar.h
#包括“NewMenu.h”//needed,因为您需要知道NewMenu的大小
类工具栏{
新菜单;
..
}
//新菜单
类工具栏;
类新菜单{

void HandleEvents(const ToolBar&ToolBar);//实际上,它是引用并不重要,不完整的类型可以作为函数声明的参数(但不能作为定义)在所有需要的类型的定义之后移动函数类是非常重要的。这有助于更多。我完全忘记了完全考虑.CPP文件了!谢谢!现在我在NeMeNeU.CPP中包含了<代码>工具栏。允许将类型作为函数声明的参数(但不允许定义)在所有需要的类型的定义之后移动函数类是非常重要的。这有助于更多。我完全忘记了完全考虑.CPP文件了!谢谢!现在我在NeMeNeU.CPP中包含了<代码>工具栏。类型被允许作为函数声明的参数(但不是定义)。在所有需要的类型的定义之后移动函数类在类之外是很重要的。这有助于更多。我完全忘记考虑.CPP文件EN。