宏类通过调用在主函数中创建对象CREATE_MAPPER("HelloMapper");
. Mapper.h 将对象注册到工厂类到class_register.h 中的宏按照下面的例子
类注册.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(接口(interface)定义):
#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() 函数不能 undefined reference ObjectCreatorRegistry_mapper_register
在宏观上?
最佳答案
鱼:
*Note that this answer was given before the OP edited the question adding this suggested fix.
编译错误是由于缺少方法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&)
方法的 undefined reference 消息 CreateObject
表示该方法具有原型(prototype),但未定义。在宏中搜索 CreateObject
显示定义是使用 CLASS_REGISTER_IMPLEMENT_REGISTRY
创建的宏。
关于一个不相关的笔记...
不要在编译行指定头文件。
g++ -g -o mapper mapper_user.cc hello_mapper.cc
关于c++ - 从工厂类创建对象名称的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25794185/