实用工具
#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/