像我之前的许多人一样,我正在努力让我的派生类型自动注册到我的工厂.我读了很多问题,并试着把注意力集中在我没有找到的地方.
除了自动注册外,我的一切运行都很顺利.
我的目标:
是)我有的:
template <class T>
class abstract_factory
{
public:
template < typename Tsub > static void register_class();
static T* create( const std::string& name );
private:
// allocator<T> is a helper class to create a pointer of correct type
static std::map<std::string, boost::shared_ptr<allocator<T> > > s_map;
}; …Run Code Online (Sandbox Code Playgroud) 我希望能够在一个std::map或一个向量中注册我的类,不要考虑重复等现在,但我不想在类构造函数调用或类的任何函数内注册它,不知何故在课外进行,所以即使我从未实例化它,我也能够知道它存在.
例:
// Somehow, from outside the myclass, in a scope that will be called
//in the begining of the proccess, add "MyClass1" to a
//list so it can be instanciated later
class MyClass1{
}
Run Code Online (Sandbox Code Playgroud)
然后我会做一个#define或如果能够,模板.
我不知道我是否清楚(再次)......我的观点是,我需要知道我所拥有的每一堂课,而不必打电话给他们每一个人.
我的想法是创建一个#define更容易声明类的标头并调用将该特定类注册到列表的东西
可以这样做还是我必须手动映射?
// desirable:
#define CLASSREGISTER(myclass) makethemagic(##myclass); class myclass {
};
Run Code Online (Sandbox Code Playgroud)
我知道,在那个定义中我不能使用继承等...我的观点是试图给出一个我想要以某种方式创建的例子......
基本上,我想为跨多个头文件定义的一堆类自动向对象工厂注册对象创建者函数。
这篇文章的最佳答案提供了一个解决方案——但它不符合我的限制。
我正在处理现有的代码库。对于我需要注册的类,在类声明之后已经有一个宏,它将类作为参数。如果我能够扩展现有的宏定义以进行注册,那么它将节省大量时间,因为无需更改现有代码。
我能想到的最接近的解决方案是创建一个宏,该宏定义注册该对象的方法的模板特化,然后调用先前定义的模板特化方法——从而链接所有寄存器调用。然后,当我想注册所有类时,我只调用最近定义的专业化,它以#include 外观的相反顺序注册所有内容。
下面,我发布了一个简单的工作示例,显示了我迄今为止的解决方案。
唯一需要注意的是,我无法自动跟踪链中要调用的最后注册类型。所以我不断将#define LAST_CHAIN_LINK 重新定义为最近的专用类型名。这意味着我必须在每个现有的宏调用之后添加两行 #undef/#define —— 我真的很想避免这种情况。
主要问题:在下面的代码中,是否有任何方法可以定义 REGISTER_CHAIN 宏以在不使用 LAST_CHAIN_LINK #undef/#define 代码的情况下工作?
如果可以在 REGISTER_CHAIN 方法中重新定义 LAST_CHAIN_LINK 令牌就好了……
我的猜测是使用__COUNTER__预处理器功能可以实现一些解决方案,但这在目标平台之一(使用 gcc 4.2.x 的 OS X)上不可用,因此不是一个选项。
简化示例(在 GNU C++ 4.4.3 上编译):
#include <map>
#include <string>
#include <iostream>
struct Object{ virtual ~Object() {} }; // base type for all objects
// provide a simple create function to derived classes
template<class T> struct ObjectT : public Object {
static Object* create() { return new T(); } …Run Code Online (Sandbox Code Playgroud) 我有方便的对象工厂模板,它按类型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文件中定义的,因此它们将被添加到每个翻译单元中.同一个对象创建者将被多次注册,更重要的是,会有很多具有静态存储持续时间的冗余对象. …