用于从工厂类创建对象名称的未定义引用
undefined reference to create object name from factory class
宏类通过调用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
类函数!
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 对 Scalar ::Scalar() 的未定义引用
- 对复制 CTOR 和 CTOR 的未定义引用
- 对显式实例化的模板函数的未定义引用
- TensorRT (C++ API) 对"createNvOnnxParser_INTERNAL"的未定义引用
- 2个模板化类的非模板友元函数未定义引用错误
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 获取对function_name的未定义引用
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 对结构方法的未定义引用
- 使用内联函数 c++ 的未定义引用
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 对 DLOPEN 的未定义引用
- QT C++中对全局变量的未定义引用
- 快速数学导致对"__pow_finite"的未定义引用
- 对 boost::system::d etail::system_category_instance 的未定义引用,从
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用