宏类通过调用CREATE_MAPPER("HelloMapper");
在main函数中创建对象。 Mapper.h在class_register.h中将对象注册到工厂类到宏,如下例所示
class_register.h
#ifndef COMMON_BASE_CLASS_REGISTER_H_
#define COMMON_BASE_CLASS_REGISTER_H_
#include <map>
#include <string>
enter code here
#define CLASS_REGISTER_DEFINE_REGISTRY(register_name, base_class_name) \
class ObjectCreatorRegistry_##register_name { \
public: \
typedef base_class_name* (*Creator)(); \
\
ObjectCreatorRegistry_##register_name() \
: m_default_creator(NULL) {} \
~ObjectCreatorRegistry_##register_name() {} \
\
void SetDefaultCreator(Creator creator) { \
m_default_creator = creator; \
} \
\
void AddCreator(std::string entry_name, Creator creator) { \
m_creator_registry[entry_name] = creator; \
} \
\
base_class_name* CreateObject(const std::string& entry_name); \
\
private: \
typedef std::map<std::string, Creator> CreatorRegistry; \
Creator m_default_creator; \
CreatorRegistry m_creator_registry; \
}; \
\
inline ObjectCreatorRegistry_##register_name& \
GetRegistry_##register_name() { \
static ObjectCreatorRegistry_##register_name registry; \
return registry; \
} \
\
class DefaultObjectCreatorRegister_##register_name { \
public: \
DefaultObjectCreatorRegister_##register_name( \
ObjectCreatorRegistry_##register_name::Creator creator) { \
GetRegistry_##register_name().SetDefaultCreator(creator); \
} \
~DefaultObjectCreatorRegister_##register_name() {} \
}; \
\
class ObjectCreatorRegister_##register_name { \
public: \
ObjectCreatorRegister_##register_name( \
const std::string& entry_name, \
ObjectCreatorRegistry_##register_name::Creator creator) { \
GetRegistry_##register_name().AddCreator(entry_name, \
creator); \
} \
~ObjectCreatorRegister_##register_name() {} \
}
#define CLASS_REGISTER_IMPLEMENT_REGISTRY(register_name, base_class_name) \
base_class_name* ObjectCreatorRegistry_##register_name::CreateObject( \
const std::string& entry_name) { \
Creator creator = m_default_creator; \
CreatorRegistry::const_iterator it = \
m_creator_registry.find(entry_name); \
if (it != m_creator_registry.end()) { \
creator = it->second; \
} \
\
if (creator != NULL) { \
return (*creator)(); \
} else { \
return NULL; \
} \
}
#define CLASS_REGISTER_DEFAULT_OBJECT_CREATOR(register_name, \
base_class_name, \
class_name) \
base_class_name* DefaultObjectCreator_##register_name##class_name() { \
return new class_name; \
} \
DefaultObjectCreatorRegister_##register_name \
g_default_object_creator_register_##register_name##class_name( \
DefaultObjectCreator_##register_name##class_name)
#define CLASS_REGISTER_OBJECT_CREATOR(register_name, \
base_class_name, \
entry_name_as_string, \
class_name) \
base_class_name* ObjectCreator_##register_name##class_name() { \
return new class_name; \
} \
ObjectCreatorRegister_##register_name \
g_object_creator_register_##register_name##class_name( \
entry_name_as_string, \
ObjectCreator_##register_name##class_name)
#define CLASS_REGISTER_CREATE_OBJECT(register_name, entry_name_as_string) \
GetRegistry_##register_name().CreateObject(entry_name_as_string)
#endif // COMMON_BASE_CLASS_REGISTER_H_
mapper.h(接口定义):
#include "class_register.h"
class Mapper {
};
CLASS_REGISTER_DEFINE_REGISTRY(mapper_register, Mapper);
#define REGISTER_MAPPER(mapper_name) \
CLASS_REGISTER_OBJECT_CREATOR( \
mapper_register, Mapper, #mapper_name, mapper_name) \
#define CREATE_MAPPER(mapper_name_as_string) \
CLASS_REGISTER_CREATE_OBJECT(mapper_register, mapper_name_as_string)`
hello_mapper.cc(Mapper的一个实现):
#include "mapper.h"
class HelloMapper : public Mapper {
};
REGISTER_MAPPER(HelloMapper);
mapper_user.cc(所有已注册地图制作者的最终用户):
#include "mapper.h"
CLASS_REGISTER_IMPLEMENT_REGISTRY(mapper_register, Mapper);
int main(){
Mapper* mapper = CREATE_MAPPER("HelloMapper");
}
编译代码后,按照
等命令行执行 g++ -g -o mapper mapper_user.cc mapper.h class_register.h hello_mapper.cc
G ++在编译完源代码后显示错误。
mapper_user.cc:line: undefined reference to ObjectCreatorRegistry_mapper_register::CreateObject(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
为什么main()函数不能在宏中对ObjectCreatorRegistry_mapper_register
进行未定义的引用?
答案 0 :(得分:2)
*请注意,在OP编辑添加此建议修复的问题之前,已给出了此答案。
编译错误是由于缺少方法ObjectCreatorRegistry_mapper_register::CreateObject()
。仅在使用CLASS_REGISTER_IMPLEMENT_REGISTRY()
时才会创建此选项。您需要将此行添加到适当的源文件中:
CLASS_REGISTER_IMPLEMENT_REGISTRY(mapper_register, Mapper);
错误消息看起来难以辨认,但如果您专注于类名和方法,则应该更容易理解:
mapper_user.cc:line:
undefined reference to
ObjectCreatorRegistry_mapper_register::CreateObject(
std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
方法 CreateObject
的未定义引用消息表明该方法具有原型,但未定义。搜索CreateObject
的宏会显示使用CLASS_REGISTER_IMPLEMENT_REGISTRY
宏创建定义。
不要在编译行上指定头文件。
g++ -g -o mapper mapper_user.cc hello_mapper.cc
答案 1 :(得分:0)
base_class_name* ObjectCreatorRegistry_##register_name::CreateObject(
由CLASS_REGISTER_DEFINE_REGISTRY
声明。这是由mapper.h编译的
它应该由宏CLASS_REGISTER_IMPLEMENT_REGISTRY
实现。但没有人称之为....所以ObjectCreatorRegistry_##register_name
类函数没有实现!