一个可配置的对象工厂实现思路如下:
1 先注册可能需要创建对象的构造函数,将其放到一个内部关联容器map中,设置键为类型的名字,值为类型的构造函数。
2 然后在创建的时候根据类型名称查找对应的构造函数并最终创建出目标对象。

可配置的对象工厂如下:

#include <string>
#include <map>
#include <memory>
#include <functional>
using namespace std;template<class T>
class IocContainer
{
public:IocContainer() {}~IocContainer() {}// 注册需要创建对象的构造函数template<class Drived>void RegisterType(string strKey){std::function<T*()> function = []{return new Drived();};RegisterType(strKey, function);}// 根据唯一标识查找对应的构造函数,并创建指针对象T* Resolve(string strKey){if (m_creatorMap.find(strKey) == m_creatorMap.end()){return nullptr;}std::function<T*()> function = m_creatorMap(strKey);return function();}// 创建智能指针对象std::shared_ptr<T> ResolveShared(string strKey){T* ptr = Resolve(strKey);return std::shared_ptr<T>(ptr);}private:void RegisterType(string strKey, std::function<T*()> creator){if (m_creatorMap.find(strKey) != m_creatorMap.end()) {throw std::invalid_argument("this key has already exist!");}m_creatorMap.emplace(strKey, creator);}private:map<string, std::function<T*()>> m_creatorMap;
};

测试代码如下:

struct ICar
{virtual ~ICar() {}virtual void test() const = 0;
};
struct Bus : ICar
{Bus() {};void test() const { cout << "Bus::test()" << endl; };
};
struct Car : ICar
{Car() {};void test() const { cout << "Car::test()" << endl; };
};int main()
{IocContainer<ICar> carioc;// Bus,ICar继承关系carioc.RegisterType<Bus>("bus");carioc.RegisterType<Car>("car");std::shared_ptr<ICar> bus = carioc.ResolveShared("bus");bus->test();std::shared_ptr<ICar> car = carioc.ResolveShared("car");car->test();return 0;
}

输出结果:

Bus::test()
Car::test()

上述代码可以创建所有的无参数的ICar派生对象。但还有如下两点不足:

(1)只能创建无参对象,不能创建有参数的对象。

(2)只能创建一种接口类型ICar的对象,通过ioccar实例不能创建所有类型的对象。

如果希望能够创建所有类型的对象,则需要通过类型擦除来实现。

[2021.7.8][11 使用C++11开发一个轻量级的IoC容器(工厂模式的应用及优化)] 11.2 IoC创建对象相关推荐

  1. [2021.7.9][11 使用C++11开发一个轻量级的IoC容器(工厂模式的应用及优化)] 11.4 通过Any和闭包来擦除类型 和 创建依赖的对象

    11.2节的对象工厂只能创建指定接口类型的对象,原因是它依赖了一个类型固定的对象构造器std::function<T*()>,这个function作为对象构造器只能创建T类型的对象,不能创 ...

  2. ESP8266开发之旅 进阶篇⑩ sniffer混杂模式,监听802.11帧,黑科技基础

    文章目录 1. 前言 1.1 混杂模式 -- sniffer 1.2 802.11 帧格式 1.2 802.11 管理帧 1.3 建立Association 2. ESP8266 sniffer应用说 ...

  3. Android开发笔记(九十一)工厂模式

    基本概念 工厂模式是一种常用的实例化对象设计模式. 程序开发很多时候都在不停地敲if.else,因为业务需求总在发展变化,今天客户要求生产A产品,明天客户要求把A产品稍微改改变成B产品,当然A产品与B ...

  4. 一周开发一个轻量级客服系统(代码开源)

    文章目录 前言 一.聊天系统为什么使用短连接? 二.技术方案 后端技术方案: 前端技术方案 原生端 三.代码详细设计 1.数据库设计 2.后端程序 3.前端程序 四.效果展示 五.源码-GitHub ...

  5. 如何开发一个Feeds流系统——写扩散模式为例

    一.了解Feeds流 在学习如何开发Feeds流应用前,我们需要先了解什么是Feeds流. 1. 什么是Feeds流 Feeds流是一个持续更新并展示给用户的信息流.它将用户主动订阅的若干消息源组合在 ...

  6. 树莓派开发实战项目 智能家居--简单工厂模式(摄像头图片获取)

    一.添加UVC驱动 有些程序采用V4L2编程,会访问到/dev/videoX设备,因此需要添加UVC驱动,针对树莓派3B/3B+可以采用如下的方法添加bcm2835-v4l2驱动: pi@raspbe ...

  7. 树莓派开发实战项目 智能家居--简单工厂模式(简单工厂模式介绍)

    一.搭建模型 二.设计模式的概念引入 1.什么是设计模式 软件设计模式(Design pattern),又称设计模式,是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是 ...

  8. java 用面向接口编程的方式开发打印机_Java面向接口编程之简单工厂模式示例

    本文实例讲述了Java面向接口编程之简单工厂模式.分享给大家供大家参考,具体如下: 一 代码 interface Output { // 接口里定义的成员变量只能是常量 int MAX_CACHE_L ...

  9. 软件设计模式与体系结构实验——2.1-1(2)(抽象)工厂模式的应用

    文章目录 一.实验三 工厂模式的应用 1.实验目的 2.实验内容 3.模式UML图 4.模式代码 5.运行截图 6.实验小结 二.实验四 抽象工厂模式的应用 1.实验目的 2.实验内容 3.模式UML ...

最新文章

  1. jQuery1·3中文参考文档下载
  2. 使用EF.Core将同一模型映射到多个表
  3. php 将颜色透明度,css中如何使颜色透明度
  4. iscsi-分区类型
  5. 四万字让你精通SQL数据库操作
  6. openeim 成片的蝴蝶兰盛开在绿树之间
  7. java mvc接收 时间_Springmvc 如何接收java8的时间localDateTime。
  8. 【C/C++ 】C++库类大全
  9. DoIP(三)—— 通信流程
  10. u-blox gps 串口驱动安装恢复解决方案
  11. sqlite转sql2000数据库
  12. 网络信息安全:数字签名
  13. 81 文件操作——关闭文件
  14. 8月AppStore最新社交App排名:soul第一,觅伊第十
  15. 如何取得cpolar的口令?
  16. 修改 vscode 中主题注释中文的斜体格式
  17. 李彦宏发布小度在家“解锁”中国家庭市场,被称作AI性价比之王
  18. 高等数学笔记-苏德矿-第九章-重积分(Ⅰ)-二重积分
  19. 搭配购买——C++详解
  20. JVM源码系列:JVM内部运行之Class的Method

热门文章

  1. html5课程总结500字,学习心得体会模板范文500字
  2. python爬虫爬取视频_python爬虫:爬取网站视频
  3. css 按钮固定在右上交_如何在iPad上交换左右鼠标按钮
  4. 视频损坏修复后卡顿声音画面口型不同步处理解决方法
  5. WPF技术触屏上的应用系列(一): 3D 图片(照片)墙、柱面墙(凹面墙或者叫远景墙、凸面墙或者叫近景墙)实现
  6. 【设计模式】创建者模式(单例工厂原型建造者)
  7. MATLAB—二维函数可视化
  8. IT 圈里有哪些经常被读错的词?
  9. Joomla建站教程:Joomla建站存在的误区
  10. Proe5.0 如何修补破面?