我正在开发一个插件框架,该框架支持基本插件类CPlugin : IPlugin的多个变体。我使用boost::shared_ptr<IPlugin>来对插件的所有引用,除非子系统需要插件类型的特定接口(interface)。我还需要能够将插件克隆到另一个单独的对象中。这必须返回PluginPtr。这就是CPlugin是模板而不是直接类的原因。 CPlugin::Clone()是使用模板参数的位置。以下是我正在使用的类定义:

IPlugin.h

#include "PluginMgr.h"
class IPlugin;
typedef boost::shared_ptr<IPlugin> PluginPtr;

class IPlugin
{
public:
  virtual PluginPtr Clone() =0;
  virtual TYPE Type() const =0;
  virtual CStdString Uuid() const =0;
  virtual CStdString Parent() const =0;
  virtual CStdString Name() const =0;
  virtual bool Disabled() const =0;

private:
  friend class CPluginMgr;
  virtual void Enable() =0;
  virtual void Disable() =0;
};

CPlugin.h
#include "IPlugin.h"
template<typename Derived>
class CPlugin : public IPlugin
{
public:
  CPlugin(const PluginProps &props);
  CPlugin(const CPlugin&);
  virtual ~CPlugin();
  PluginPtr Clone();

  TYPE Type() const { return m_type; }
  CStdString Uuid() const { return m_uuid; }
  CStdString Parent() const { return m_guid_parent; }
  CStdString Name() const { return m_strName; }
  bool Disabled() const { return m_disabled; }

private:
  void Enable() { m_disabled = false; }
  void Disable() { m_disabled = true; }

  TYPE        m_type;
  CStdString  m_uuid;
  CStdString  m_uuid_parent;
  bool        m_disabled;
};

template<typename Derived>
PluginPtr CPlugin<Derived>::Clone()
{
  PluginPtr plugin(new Derived(dynamic_cast<Derived&>(*this)));
  return plugin;
}

具体示例类CAudioDSP.h
#include "Plugin.h"
class CAudioDSP : CPlugin<CAudioDSP>
{
  CAudioDSP(const PluginProps &props);
  bool DoSomethingTypeSpecific();
  <..snip..>
};

我的问题(最后)是CPluginMgr需要更新具体类的m_disabled,但是当它传递给PluginPtr时,它无法确定类型并根据模板参数来表现不同。我无法避免如何避免将::Enable()::Disable()声明为IPlugin的私有(private)成员,但这立即意味着应用程序的每个部分现在都需要了解CPluginMgr类,因为它在 header 中被声明为好友。随之而来的是循环依赖 hell 。我看到了另一个选项,将Enable / Disable函数声明为CPlugin的私有(private)成员,并改为使用boost::dynamic_pointer_cast<CVariantName>
void CPluginMgr::EnablePlugin(PluginPtr plugin)
{
  if(plugin->Type == PLUGIN_DSPAUDIO)
  {
    boost::shared_ptr<CAudioDSP> dsp = boost::dynamic_pointer_cast<CAudioDSP>(plugin);
    dsp->Enable();
  }
}

但是,这会导致许多重复的代码,以及基本CPlugin模板的多种变体。如果有人有更好的建议,请分享!

最佳答案

您可以轻松地编写:

class CPluginMgr;

class IPlugIn ..
{
    friend CPluginMgr;
    ...
};

friend 只需要一个预定义。

关于c++ - 模板化类的接口(interface),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1255545/

10-11 19:08