我一直在研究 Curiously Recurring Template Pattern 以确定如何使用它来实现桥接设计模式。
我的问题是将 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);
}
};