我正在研究一個插件框架,它支持基類插件類CPlugin : IPlugin
的多個變體。我使用boost::shared_ptr<IPlugin>
來引用所有插件,除非子系統需要插件類型的特定接口。我還需要能夠將插件克隆到另一個分離對象中。這必須返回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
的私人成員,但是這意味着應用程序的每個部分現在都需要知道CPluginMgr
類,因爲它在頭中被聲明爲好友。循環依賴地獄發生。我看到另一個選項,將啓用/禁用功能聲明爲CPlugin的私有成員,並使用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
模板的許多多個變種。如果有人有更好的建議,請分享!
爲什麼'CPlugin'是模板化的?你應該知道一個類可以是一個非模板,但有一個模板化的成員函數(在本例中爲克隆)。 – 2009-08-10 15:48:14
也許我正在做點什麼,但是你不能這樣做:'plugin-> Enable();'如果plugin的類型是'PluginPtr' ?.這是接口的點... – 2009-08-10 15:50:44
我不希望除CPluginMgr以外的任何其他類能夠禁用/啓用插件 – AlasdairC 2009-08-10 16:27:00