Utilities.h
#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_
Utilities.cpp
#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)
我哪里错了?
答案 0 :(得分:1)
Utilities.h包含MyFirstCairoPlugin.h,MyFirstCairoPlugin.h包含Utilities.h,即圆形,逻辑上导致循环依赖。
这是你应该做的事情:
如果一个类在声明中需要另一个类,或者它显然是其中最重要的部分,请包括它。示例:一个班级"图像"可能包括一个班级"颜色" 如果一个类在某种程度上使用了另一个类,比如将它存储在指针中或者在调用某个方法时使用它,请使用forward声明。 如果它根本不需要其他类,那么它也不会。 对于第二种情况,实现文件将包含依赖类。
在您的情况下,MyFirstCairoPlugin存储指向Utilities的指针,因此它应该执行Utilities的前向声明,但不包括它。顺便说一句,该指针不应该是公开的。
这里应该是这样的:
#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,那么没问题,它已经有一个前向声明。但是,不会在宏观上做到这一点。而是将Utilities作为模板类。顺便说一下,&#34; Utilities&#34;是一个相当广泛的名称,听起来很容易导致名称冲突。
看起来像这样:
#ifndef _UTILITIES_
#define _UTILITIES_
template<class T>
class Utilities
{
private:
T* pPlug;
public:
Utilities(T* plug);
...
编辑:似乎你似乎对模板不满意,这是另一种可能性:
创建一个抽象类(/接口),其中MyFirstCairoPlugin将是一个子类,提供Utilities实现中所需的所有方法。让我们说它被称为&#34;插件&#34;。看来你已经有了这样的课程,但是因为我不知道IPlug是什么,所以我选择其他名字。
围绕插件而不是MyFirstCairoPlugin或PLUG_CLASS_NAME构建实用程序。然后简单地为它提供一个MyFirstCairoPlugin实例,这是一个有效的插件实例。只要插件的方法是抽象的和虚拟的,在Plugin指针上调用方法就会调用MyFirstCairoPlugin的方法,每个人都很高兴。
答案 1 :(得分:0)
了解它是如何逐步包含的:
Utilities.h
#define _UTILITIES_
MyFirstCairoPlugin.h
Utilities.h
#ifndef _UTILITIES_
,未包含类定义 - _UTILITIES_
已定义(请参阅第二步)!所以class Utilities
尚未定义,您需要转发声明。