私は Curiously Recurring Template パターンを調査して、それを使用して Bridge Design パターンを実装する方法を決定しました。
私の問題は、オーバーライドするメソッドが実際にテンプレート化されているため、IBridgeConnector::GetBridgeImpl メソッドを Bridge::GetBridgeImpl メソッドに接続 (接続) することです。
この場合、仮想ディスパッチは機能しないため、これらのメソッドを相互にポイントする最良の方法は何ですか? 関数デリゲート? これにはより良いパターンがありますか?
これはどのように行うべきですか?
助けてくれてありがとう!
どこでも shared_ptrs と OpenGL および DirectX 呼び出しなしでできる限りのコードの簡素化を行いました。:) うまくいけば、これは将来誰かに役立つでしょう!
#include <string>
/********************************************************************/
class BridgePart
{
public:
BridgePart * OtherPart;
};
/********************************************************************/
// Connects a BridgeSource and a BridgeImplementation
class BridgeConnector
{
public:
static BridgeConnector * implementor;
// Need a way, (Function Delegates?) to point this method
// This method will loop until stack overflow.
template <typename ValueTemplateType>
BridgePart * GetBridgeImpl(ValueTemplateType * source)
{
return implementor->GetBridgeImpl<ValueTemplateType>(source);
}
};
BridgeConnector * BridgeConnector::implementor = nullptr;
/********************************************************************/
// Where the Magic is At, (CRTP)
template <typename BridgeImplementationTemplateType>
class Bridge : public BridgeConnector
{
public:
template <typename ValueTemplateType>
IBridgePart * GetBridgeImpl(IBridgePart * source)
{
// NOTE: This method never gets called.
// CRTP Magic Here to Semi-Specify Pure Virtual Methods
return static_cast<BridgeImplementationTemplateType>(this)
->GetBridgeImpl( (ValueTemplateType) source);
}
};
/********************************************************************/
class BridgeImplementation1 :
public Bridge<BridgeImplementation1>,
public BridgePart
{
public:
class CustomImpl : public BridgePart
{
public:
template <typename SourceTemplateType>
BridgePart(SourceTemplateType source){}
/* Does proprietary stuff. */
};
template <typename ValueTemplateType>
BridgePart * GetBridgeImpl(ValueTemplateType & source)
{
return new CustomImpl<ValueTemplateType>(source);
}
// Constructor
BridgeImplementation1()
{
}
};
/********************************************************************/
class BridgeSource1 : public BridgePart {};
class BridgeSource2 : public BridgePart {};
class Client
{
BridgeSource1 source1;
BridgeSource2 source2;
BridgeConnector * connector;
bool usingImpl1;
Client()
{
usingImpl1 = true; // from config file.
connector = new BridgeConnector();
connector->implementor = usingImpl1
? (BridgeConnector *) new BridgeImplementation1()
: nullptr; // (BridgeConnector *) new BridgeImplementation2();
// removed to shorten code.
}
void Init()
{
source1.OtherPart = connector->GetBridgeImpl<BridgeSource1>(& source1);
source2.OtherPart = connector->GetBridgeImpl<BridgeSource2>(& source2);
}
};