c++ - 从工厂类创建对象名称的 undefined reference

标签 c++ macros factory-pattern

宏类通过调用在主函数中创建对象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/

相关文章:

python - 使用 Cython 包装具有 OpenCV 参数的 C++ 函数

C 预处理器宏替换

Java - 如何正确地将抽象工厂与工厂方法结合起来?

c# - 在 C# 中使用 C++ dll

c++ - 使用Cmake编译LZO时提示找不到任何VS实例

C++ 函数注释/契约

scala - 如何查看 Scala 用于自动生成案例类的 apply 函数的代码?

c++ - 如何从 `Status` 中避免全局定义的 `Xlib.h` C 宏?

c# - 角色、抽象模式、松耦合

c++ - C++ 中灵活的应用程序配置