C++中实现自动注册的工厂
2016-01-23 13:44
513 查看
很长时间没有更新博客了,不是博主懒,是因为博主在帮研究生妹子弄硕士论文,定位方面的,被imu,行人航迹,激光匹配各种虐,不说了,都是泪。
Factory模式,在工程中多用了创建派生类实例,内部一般使用switch-case根据不同的key去创建不同的派生类对象。
对于继承体系简单的,这种还可以,如果对于一个复杂的体系,比如一个命令系统,最后其有100多个业务命令的类,那难道你还想把switch-case写成和懒婆娘的裹脚布一样,又臭又长,显然是不可以的,今天我们就来实现一个自动注册的工厂。
其实这个设计思路我在很早之前就看过,第一次好像是在cpp博客,第二次是在csdn,最近cpp社区“行知一”又看见了,但是他们那个只是一个demo代码,虽然这里我们只是简单的写写,但是尽量让其可以直接使用。
其实思路很简单,借助于map数据结构,标示类唯一的身份标记作为map的key,而value则是一个lambda表达式,其用来产生类实例。
factory的代码如下:
默认使用string来作为键值。
其他的一些函数就是一些基础的功能,无非就是查找操作。
简单的使用demo,Object是我们的基类,然后其有一个Widget子类。
main.cpp
object.h中的几个宏封装了细节。但是比如
新的一个类继承体系,宏写了一遍,但是这些宏的动作十分的相似,还是可以再抽象一下。
代码:https://github.com/ZhouBox/ccfactory.git
Factory模式,在工程中多用了创建派生类实例,内部一般使用switch-case根据不同的key去创建不同的派生类对象。
[code]switch(Key) { case A: return new A; case B: return new B; ... }
对于继承体系简单的,这种还可以,如果对于一个复杂的体系,比如一个命令系统,最后其有100多个业务命令的类,那难道你还想把switch-case写成和懒婆娘的裹脚布一样,又臭又长,显然是不可以的,今天我们就来实现一个自动注册的工厂。
其实这个设计思路我在很早之前就看过,第一次好像是在cpp博客,第二次是在csdn,最近cpp社区“行知一”又看见了,但是他们那个只是一个demo代码,虽然这里我们只是简单的写写,但是尽量让其可以直接使用。
其实思路很简单,借助于map数据结构,标示类唯一的身份标记作为map的key,而value则是一个lambda表达式,其用来产生类实例。
factory的代码如下:
[code]#ifndef FACTORY #define FACTORY #include <string> #include <map> #include <functional> using namespace std; template <typename T, typename K = std::string> class Factory { public: typedef T type_value; template <typename N> struct register_h { register_h(const K& key) { Factory::instance()->m_creators[key] = []{ return new N; }; } }; static auto instance() -> Factory<T>* { static Factory<T> f; return &f; } auto creat(const K& key) -> T* { T* re = NULL; auto ite = m_creators.find(key); if (ite != m_creators.end()) { re = (ite->second)(); } return re; } static auto produce(const K& key) -> T* { return Factory::instance()->creat(key); } private: Factory() {} Factory(const Factory&) = delete; Factory(Factory&&) = delete; Factory& operator =(const Factory&) = delete; std::map<K, std::function<T*()>> m_creators; }; #define CLASS_NAME(CLASS) #CLASS #endif // FACTORY
默认使用string来作为键值。
register_h类是很重要的一步,我们借组于其的实例化来完成注册动作。
其他的一些函数就是一些基础的功能,无非就是查找操作。
简单的使用demo,Object是我们的基类,然后其有一个Widget子类。
[code]#ifndef OBJECT #define OBJECT #include "factory.h" class Object { public: virtual ~Object() {} }; #define FACTORY_OBJECT Factory<Object> #define REGISTER_OBJECT_CLASS_KEY(CLASS, KEY) \ FACTORY_OBJECT::register_h<CLASS> __##CLASS(KEY) #define REGISTER_OBJECT_CLASS(CLASS) \ REGISTER_OBJECT_CLASS_KEY(CLASS, CLASS_NAME(CLASS)) #endif // OBJECT
[code]#ifndef WIDGET_H #define WIDGET_H #include "object.h" class Widget : public Object { public: Widget(); }; #endif // WIDGET_H
[code]#include "widget.h" Widget::Widget() { } REGISTER_OBJECT_CLASS(Widget);
REGISTER_OBJECT_CLASS(Widget);这句代码完成了注册,其实例化一个命名为__Widgt的
Factory<Object>::register_h<Widget>对象,在构造函数中现实了自动注册。
main.cpp
[code]#include <iostream> #include "widget.h" using namespace std; int main() { Widget *p = static_cast<Widget*>(FACTORY_OBJECT::produce("Widget")); FACTORY_OBJECT::type_value* p1 = FACTORY_OBJECT::produce("Text"); std::cout << p1; std::cout << "\n-----------------"; std::cout << p; std::cout << "Hello World!" << std::endl; delete p; delete p1; return 0; }
object.h中的几个宏封装了细节。但是比如
[code]#ifndef MESSAGE #define MESSAGE #include "factory.h" class Message { }; #define FACTORY_MESSAGE Factory<Message> #define REGISTER_MESSAGE_CLASS_KEY(CLASS, KEY) \ FACTORY_MESSAGE::register_h<CLASS> __##CLASS(KEY) #define REGISTER_MESSAGE_CLASS(CLASS) \ REGISTER_MESSAGE_CLASS_KEY(CLASS, CLASS_NAME(CLASS)) #endif // MESSAGE
新的一个类继承体系,宏写了一遍,但是这些宏的动作十分的相似,还是可以再抽象一下。
代码:https://github.com/ZhouBox/ccfactory.git
相关文章推荐
- C++中的返回值优化(RVO)
- C语言中为什么不能把char**赋给const char**
- Android使用NDK编译C/C++文件
- C++学习笔记(一) C++介绍
- C++Primer第5版学习笔记(二)
- C++四种智能指针小结
- C++中的右值引用"&&"
- C++ 顺序容器基础知识总结
- C++ 析构函数——转自“九天雁翎”博客
- x265-1.7版本-encoder/encoder.cpp注释
- 打破C++ Const 的规则
- x265-1.7版本-encoder/dpb.cpp注释
- x265-1.7版本-encoder/bitcost.cpp注释
- Google C++编程风格指南(一)之头文件的相关规范
- Google C++编程风格指南(一)之头文件的相关规范
- 文章标题
- C/C++语言中 “#if 0/#if 1 ... #endif”的作用
- c++ 11 sleep()
- x265-1.7版本-common/threadpool.cpp注释
- C++之路进阶——差分约束(FFF的后宫)