实用工具

#ifndef _UTILITIES_
#define _UTILITIES_

#include "MyFirstCairoPlugin.h"

class PLUG_CLASS_NAME;

class Utilities
{
private:
    PLUG_CLASS_NAME *pPlug;

public:
    Utilities(PLUG_CLASS_NAME *plug);
    ~Utilities();
};

#endif // !_UTILITIES_


实用工具

#include "Utilities.h"

Utilities::Utilities(PLUG_CLASS_NAME *plug) : pPlug(plug) {
    IColor color = IColor(100, 100, 100, 255);
}
Utilities::~Utilities() {

}


这是我麻烦的地方,使用MyFirstCairoPlugin.h中的此类:

#ifndef _MYFIRSTCAIROPLUGIN_
#define _MYFIRSTCAIROPLUGIN_

#include "IPlug_include_in_plug_hdr.h"
#include "resource.h"

#include "Utilities.h"

//class Utilities;

class MyFirstCairoPlugin : public IPlug
{
private:

public:
    Utilities *pUtilities;

    MyFirstCairoPlugin(IPlugInstanceInfo instanceInfo);
    ~MyFirstCairoPlugin();
};

#endif // !_MYFIRSTCAIROPLUGIN_


如果我不注释//class Utilities;(前向声明),它将无法使用实用程序(即使我已经在#include "Utilities.h"中包括了它)。它给了我“典型的”循环依赖错误`:

syntax error: missing ';' before '*' (compiling source file ..\..\..\IPlug_AddOns\Utilities.cpp)


我哪里错了?

最佳答案

Utilities.h包含MyFirstCairoPlugin.h,MyFirstCairoPlugin.h包含Utilities.h(即一个圆),从逻辑上讲导致圆依赖。

您应该改用以下方法:

如果一个类在声明中需要另一个类权利,或者如果它显然是其中最重要的一部分,则将其包括在内。示例:“图像”类可能包括“颜色”类
如果一个类在某种程度上使用另一个类,例如将其存储在指针中或在某个方法的调用中使用它,请使用前向声明。
如果它根本不需要另一个类,那么,它也不做。
对于第二种情况,实现文件将包括从属类。

在您的情况下,MyFirstCairoPlugin存储指向实用程序的指针,因此它应该对实用程序进行前向声明,但不包括它。顺便说一句,该指针不应是公共的。

这里看起来应该是这样的:

#ifndef _MYFIRSTCAIROPLUGIN_
#define _MYFIRSTCAIROPLUGIN_

#include "IPlug_include_in_plug_hdr.h" //<--- no idea what that is about
#include "resource.h"

class Utilities;

class MyFirstCairoPlugin : public IPlug
{
private:

public:
    Utilities* pUtilities; //<-- shouldn't be public, you should always use encapsulation
...


另一方面,实用程序甚至不使用MyFirstCairoPlugin,因此我们在这里有了第三种情况。您为什么首先使它包含MyFirstCairoPlugin?如果该宏可能是MyFirstCairoPlugin,那么没问题,它已经有一个前向声明。但是,不会在宏上执行此操作。而是将实用程序作为模板类。顺便说一句,“实用程序”是一个相当广泛的名称,听起来它很容易导致名称冲突。

可能看起来像这样:

#ifndef _UTILITIES_
#define _UTILITIES_

template<class T>
class Utilities
{
private:
    T* pPlug;

public:
    Utilities(T* plug);
...


编辑:似乎您似乎对模板不满意,这是另一种可能性:

创建一个抽象类(/接口),该类的MyFirstCairoPlugin将作为其子类,提供实用工具实现中所需的所有方法。假设它称为“插件”。看来您已经有了这样的课程,但是由于我不知道IPlug是什么,因此我改用另一个名称。

围绕插件而不是MyFirstCairoPlugin或PLUG_CLASS_NAME构建实用程序。然后只需向其提供MyFirstCairoPlugin的实例,该实例便是Plugin的有效实例。只要Plugin的方法是抽象的和虚拟的,在指向Plugin的指针上调用方法将调用MyFirstCairoPlugin的方法,并且每个人都很高兴。

关于c++ - 为什么我在这里遭受循环依赖?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40991478/

10-11 18:30