我已经实现了这样的模板化缓冲区类:
template <class T, class Impl>
class base_hardware_buffer : Impl
{
public:
typedef const T& const_reference;
typedef T* pointer;
void push_back(reference r)
{
// Do some generic operation, call impl when needed
// ...
}
pointer map()
{
static_cast<Impl*> (this)->map();
}
// ... etc
};
然后,我定义了两个实现,一个用于OpenGL,一个用于DirectX,每个实现都在各自的动态库中实例化。
对于OpenGL:
template <class T>
class glBuffer : base_hardware_buffer<T, glBuffer<T> >
{
public:
typedef T* pointer;
pointer map()
{
// Actual implementation of map
}
// Other implementation specific operation and members go here
};
这一切都很好,并且效果很好。
现在我的问题是,在子系统上方的层上工作的队友希望实现一种需要访问缓冲区的算法。
我如何才能给他一个统一的缓冲区访问权限,而又不将特定的实现公开/硬编码到他的代码中,又不损害类型安全性呢?
最佳答案
我可以解释一下我如何实现类似问题的解决方案。
基本上,我有一个“ CreateBuffer”函数,该函数返回一个指向“基本”缓冲区的指针。然后,当我在该基本缓冲区上调用函数时,它们将移至相关函数。
class BaseBuffer
{
public:
BaseBuffer(void);
virtual ~BaseBuffer(void);
virtual bool Init( GFXHandler* pHandler, unsigned int usage, unsigned int sizeofData ) { return false; }
virtual bool Shutdown() = 0;
virtual bool LockBuffer( unsigned int flags, void** ppData ) = 0;
virtual bool UnlockBuffer() = 0;
};
现在,我用来确保最终用户不在乎缓冲区的后端实现的技巧是使“ CreateBuffer”成为函数指针。然后,当我设置图形处理程序(例如GL2Handler)时,将“ GL2CreateBuffer”函数分配给“ CreateBuffer”函数指针。
这样,最终用户就可以执行以下操作:
BaseBuffer* pBuffer = CreateBuffer();
pBuffer->Init( /*init params*/ );
void* pData = NULL;
pBuffer->LockBuffer( /*lock flags*/, &pData );
memcpy( pData, pOriginalData, sizeOfOriginalData );
pBuffer->UnlockBuffer();
任务完成。如果创建了D3D9Handler,则使用D3D9实现;如果创建了GL2Handler,则使用GL2实现等。
编辑:要回答您的评论,您不仅可以执行以下操作:
template< typename Type > bool LockBuffer( unsigned int flags, Type** pData );
还是要专门创建一个类,其中唯一的可返回类型是创建它的类型?由于您突然有大量不同类型的数据需要分配给各种函数指针,所以这会有点复杂,因为将2个单独的类型传递到模板中会创建2个不同的函数。