boc*_*cco 2 c++ implementation design-patterns visual-c++
我有方便的对象工厂模板,它按类型ID名称创建对象.实现非常明显:ObjectFactory包含从std::string对象创建者函数的映射.然后,所有要创建的对象都应在此工厂中注册.
我使用以下宏来做到这一点:
#define REGISTER_CLASS(className, interfaceName) \
class className; \
static RegisterClass<className, interfaceName> regInFactory##className; \
class className : public interfaceName
Run Code Online (Sandbox Code Playgroud)
这里RegisterClass是
template<class T, class I>
struct RegisterClass
{
RegisterClass()
{
ObjectFactory<I>::GetInstance().Register<T>();
}
};
Run Code Online (Sandbox Code Playgroud)
用法
class IFoo
{
public:
virtual Do() = 0;
virtual ~IFoo() {}
}
REGISTER_CLASS(Foo, IFoo)
{
virtual Do() { /* do something */ }
}
REGISTER_CLASS(Bar, IFoo)
{
virtual Do() { /* do something else */ }
}
Run Code Online (Sandbox Code Playgroud)
类在工厂中同时定义和注册.
问题是regInFactory...静态对象是在.h文件中定义的,因此它们将被添加到每个翻译单元中.同一个对象创建者将被多次注册,更重要的是,会有很多具有静态存储持续时间的冗余对象.
有没有办法做这样优雅的注册(不是复制/粘贴类和接口名称),但是不要在全球范围内传播冗余的静态对象?
如果一个好的解决方案需要一些VC++特定的扩展(不符合C++标准),我会很好.
所以你想把变量定义放在头文件中?有一种可移植的方式:模板类的静态变量.所以我们得到:
template <typename T, typename I>
struct AutoRegister: public I
{
// a constructor which use ourRegisterer so that it is instantiated;
// problem catched by bocco
AutoRegister() { &ourRegisterer; }
private:
static RegisterClass<T, I> ourRegisterer;
};
template <typename T, typename I>
RegisterClass<T, I> AutoRegister<T, I>::ourRegisterer;
class Foo: AutoRegister<Foo, IFoo>
{
public:
virtual void Do();
};
Run Code Online (Sandbox Code Playgroud)
请注意,我保留了IFoo非虚拟的继承.如果有多次从该类继承的风险,它应该是虚拟的.
| 归档时间: |
|
| 查看次数: |
8896 次 |
| 最近记录: |