Qt循环类及其成员之间的依赖关系

时间:2013-07-15 08:59:50

标签: c++ qt circular-dependency

这是C ++。我有一个主要课程:

#include <QObject>

#include "Logger.h"
#include "PluginManager.h"

class Main : QObject
{
  Main();
  ~Main();
  Logger &getLogger();

signals:
  // Some signals

public slots:
  // Some slots
};

现在我有了PluginManager类。

构造函数是:

PluginManager( QObject *parent = 0 );

我在这样的主类中构建它:

pluginManager = new PluginManager(this);

现在,问题是:服务器类需要创建PluginManager(显然),PluginManager也必须从服务器类获取所有插件的记录器!

parent()->getLogger(); // This doesn't work (PluginManager)

错误:'class QObject'没有名为'getLogger'的成员

我是否要创建一个类并从所有类派生它? 请提供任何有用的示例。

提前致谢。

3 个答案:

答案 0 :(得分:1)

要面对编译时依赖项,有两种方法:

  1. 转发声明您需要的课程。
  2. 使用接口来打破循环依赖关系。
  3. 前瞻性声明

    PluginManager.h文件中,您只需编写

    class Main;
    

    位于您的文件顶部,以便转发声明Main。然后将PluginManager的构造函数声明为

    PluginManager( Main * parent );
    

    PluginManager的实现文件中,您需要包含定义Main类的标头。

    接口

    第二个选项使用接口完全避免循环依赖。它的工作原理如下:

    class MainInterface : public QObject
    {
        Q_OBJECT
    public:
        MainInterface( QObject * parent ) : QObject(parent) {}
        virtual ~MainInterface() {}
        virtual void someFunc1() = 0;
        virtual void someFunc2() = 0;
        // ...
    };
    
    class PluginManager : public QObject
    {
        Q_OBJECT
    public:
        PluginManager( MainInterface * parent = 0 ) 
            : QObject(parent) { /* ... */ }
        // ... other functions ...
    };
    
    class Main : public MainInterface
    {
    public:
        Main( QObject * parent = 0 )
            : MainInterface(parent) {}
        virtual void someFunc1();
        virtual void someFunc2();
        // ...
    };
    

    依赖图现在看起来像这样

    MainInterface                          PluginManager
      A       A              instead of        A  |
      |       |                                |  V
    Main   PluginManager                       Main
    

    您的选择

    您想要使用的替代方案是您的选择。如果这两个类一起作为程序中不可分割的一部分,则使用更容易的前向声明方法。如果您希望将这些组件分离并尽可能避免依赖,那么请使用第二种方法。

答案 1 :(得分:0)

到目前为止,错误“'类QObject'没有名为'getLogger'的成员”,它与循环依赖无关。

PluginManager( QObject *parent = 0 )

父类型是QObject *,它没有成员getLogger(),它是Main类的成员。

答案 2 :(得分:0)

记录器部件是否在应用程序中不断变化?

如果没有,那么在创建PluginManager时你也应该通过传递一个额外的参数初始化logger,删除插件管理器在服务器上的后续依赖