用于从工厂类创建对象名称的未定义引用

undefined reference to create object name from factory class

本文关键字:未定义 引用 创建对象 工厂 用于      更新时间:2023-10-16

宏类通过调用CREATE_MAPPER("HelloMapper");在主函数中创建对象。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(映射器的实现(:

 #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的引用?

鱼:

*请注意,此答案是在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

base_class_name* ObjectCreatorRegistry_##register_name::CreateObject(CLASS_REGISTER_DEFINE_REGISTRY声明。由mapper.h编译

它应该由宏CLASS_REGISTER_IMPLEMENT_REGISTRY实现。但是没有人叫它....所以没有实现ObjectCreatorRegistry_##register_name类函数!