私はプラグインフレームワークで作業しています。これは、ベースプラグインクラスの複数のバリエーションをサポートしていますCPlugin : IPlugin
。サブシステムがプラグインタイプの特定のインターフェースを必要とする場合を除いて、プラグインへのすべての参照にboost::shared_ptr<IPlugin>
を使用しています。私はまた別のseprateオブジェクトにプラグインを複製する機能が必要です。これは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..>
};
私の問題(最後に)は、PluginPtr
が渡されるので、具体的なクラスのm_disabled
を更新する必要があるということです(PluginPtr
)。それは型を決定し、テンプレートのパラメータに従って異なる動作をする方法がありません。 ::Enable()
と::Disable()
をプライベートメンバーとしてIPlugin
の代わりに宣言しないようにする方法はわかりませんが、これは即座にアプリケーションの各セクションがヘッダーのフレンドとして宣言されたCPluginMgr
クラスについて知る必要があることを意味します。円の依存関係が続いている。別のオプションが表示され、CPluginのプライベートメンバーとしてEnable/Disable機能を宣言し、代わりに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'はテンプレート化されていますか?クラスは非テンプレートでもテンプレート化されたメンバ関数(この場合はクローン)を持つことができます。 –
たぶん私は何かを手に入れているかもしれませんが、プラグインのタイプが 'PluginPtr'の場合、' plugin-> Enable(); 'を実行することはできません。それはインターフェイスのポイントのようなものです... –
CPluginMgr以外のクラスではプラグインを無効/有効にすることはできません – AlasdairC