C++里面缺少一些有用的框架比如说AOP和IOC等,AOP框架的实现在前面的博文中已介绍了,现在介绍IOC框架。

IOC即控制反转,它的思想是由IOC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分开。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。IOC不仅仅用来解除对象创建的耦合性,还可以使我们能通过配置去创建我们需要的对象,这种灵活性在我们应用开发过程中是非常有用的。C#和Java中有很多IOC框架,遗憾的是C++中却鲜有IOC框架,本IOC框架填补了这个遗憾。

IOC框架的实现原理:通过向IOC容器注册类型信息和一个唯一key,在创建时,根据类型信息和key从容器中创建一个实例。下面具体看实现代码:

#include <string>
#include <map>
#include <memory>
#include <functional>
using namespace std;
#include <Any>
#include<NonCopyable>class IocContainer : NonCopyable
{
public:IocContainer(void){}~IocContainer(void){}template <class T>void RegisterType(string strKey){typedef T* I;std::function<I()> function = Construct<I, T>::invoke;RegisterType(strKey, function);}template <class I, class T, typename... Ts>void RegisterType(string strKey){std::function<I* (Ts...)> function = Construct<I*, T, Ts...>::invoke;RegisterType(strKey, function);}template <class I>I* Resolve(string strKey){if (m_creatorMap.find(strKey) == m_creatorMap.end())return nullptr;Any resolver = m_creatorMap[strKey];std::function<I* ()> function = resolver.AnyCast<std::function<I* ()>>();return function();}template <class I>std::shared_ptr<I> ResolveShared(string strKey){auto b = Resolve<I>(strKey);return std::shared_ptr<I>(b);}template <class I, typename... Ts>I* Resolve(string strKey, Ts... Args){if (m_creatorMap.find(strKey) == m_creatorMap.end())return nullptr;Any resolver = m_creatorMap[strKey];std::function<I* (Ts...)> function = resolver.AnyCast<std::function<I* (Ts...)>>();return function(Args...);}template <class I, typename... Ts>std::shared_ptr<I> ResolveShared(string strKey, Ts... Args){auto b = Resolve<I, Ts...>(strKey, Args...);return std::shared_ptr<I>(b);}private:template<typename I, typename T, typename... Ts>struct Construct{static I invoke(Ts... Args) { return I(new T(Args...)); }};
void RegisterType(string strKey, Any constructor){if (m_creatorMap.find(strKey) != m_creatorMap.end())throw std::logic_exception("this key has already exist!");m_creatorMap.insert(make_pair(strKey, constructor));}private:unordered_map<string, Any> m_creatorMap;
};

使用说明:

类型注册分成三种方式注册,一种是简单方式注册,它只需要具体类型信息和key,类型的构造函数中没有参数,从容器中取也只需要类型和key;另外一种简单注册方式需要接口类型和具体类型,返回实例时,可以通过接口类型和key来得到具体对象;第三种是构造函数中带参数的类型注册,需要接口类型、key和参数类型,获取对象时需要接口类型、key和参数。返回的实例可以是普通的指针也可以是智能指针。需要注意的是key是唯一的,如果不唯一,会产生一个断言错误,推荐用类型的名称作为key,可以保证唯一性,std::string strKey = typeid(T).name()。

由于用到了C++11的可变模板参数,所以对编译器有要求,windows中需要vs2012的Microsoft Visual C++ Compiler Nov 2012 CTP;linux GCC4.7及以上。

测试代码:

struct ICar
{virtual ~ICar(){}virtual void test() const = 0;
};
struct Bus : ICar
{Bus(int i, float f) {};void test() const { std::cout << "Bus::test()"; }
};class IX
{
public:IX(){}virtual ~IX(){}virtual void g()=0;
private:};class X : public IX
{
public:void g() {std::cout << "it is a test" << std::endl;}
};    void TestMyIoc()
{//简单注册,需要类型信息和key
    IocContainer ioc;ioc.RegisterType<X>("ss");ioc.RegisterType<X>("ss");//key重复,会报错auto ix = ioc.ResolveShared<X>("ss");ix->g();//简单注册,需要类型信息、接口类型和keyioc.SimpleRegisterType<IX, X>("ff");auto ix1 = ioc.ResolveShared<IX>("ff");ix1->g();//含参数的类型注册,需要类型信息、接口类型、参数类型和keyioc.RegisterType<ICar, Bus, int, float>("bus");int a=1;float b= 2.0;auto mycar = ioc.ResolveShared<ICar>("bus", a, b);mycar->test();
}    

测试结果:

it is a test
it is a test
Bus::test()

补充一点:当resolve的参数类型为指针类型时,直接将nullptr作为参数传入会报异常,应该讲nullptr强制转换为注册时的参数类型。

ioc.Resolve<BaseAppChain>(str, (BaseAppChain*)nullptr);

转载于:https://www.cnblogs.com/qicosmos/archive/2013/04/22/3035074.html

(原创)C++ IOC框架相关推荐

  1. spring根据名称获取bean_带你从零开始手写 spring ioc 框架,深入学习 spring 源码

    IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...

  2. .NET领域最为流行的IOC框架之一Autofac

    一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程序也是用的Autofac. Orchad和Nopcomm ...

  3. java轻量级IOC框架Guice

    Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于: 速度快,号称比spring快100倍. 无外部配置(如需要使用外部可以可以选用Guice的扩展包) ...

  4. 使用注解打造自己的IOC框架

    一.简述 IoC和AOP可谓是后台开发入门必学的知识(Spring相关),但这两者都仅仅只是概念而已,并非具体技术实现,同样的,Android也可以使用IoC和AOP,之前已经写过如何在Android ...

  5. [原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇)...

    .NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇) 前言:这个系列有段时间没有动了.主要是针对大家的反馈在修改代码.在修改的过程中,也有了一些新的体会,这里和大家分享一下,同时也 ...

  6. 教你打造 Android 中的 IOC 框架

    1.概述 首先我们来吹吹牛,什么叫IoC,控制反转(Inversion of Control,英文缩写为IoC),什么意思呢? 就是你一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量, ...

  7. .Net IOC框架入门之三 Autofac

    一.简介 Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个 目的 1.依赖注入的目的是为了解耦. 2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置. 3.控制反转即Io ...

  8. [原创].NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略

    .NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略 前言:之前的讨论一直关注在怎么从DAL中获取数据,以及数据的Mapping问题.实际上,一个业务框架最主要的作用就是简化业务 ...

  9. Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

最新文章

  1. RHEL7.0系列 修改字符终端分辨率
  2. js在PageOffice打开的Word文档光标处插入书签
  3. 计算机基础操作与应用实训教程,计算机应用基础实训教程の第 3 章 Word 2003 基本操作.pdf...
  4. Linux下进程间通信方式——信号量(Semaphore)
  5. code block怎样导入整个文件夹_按需分配随时可用的在线开发环境:弹性容器+code-server踩坑记...
  6. Spring 3.1 –从数据库加载XML配置的属性
  7. 第6/24周 聚集索引
  8. VLM:Meta AI CMU提出任务无关视频语言模型视频理解预训练VLM,代码已开源!(ACL 2021)...
  9. hive内部表和外部表的区别_走近大数据之Hive进阶(四、Hive的表连接)
  10. 怀旧系列(5)----大学时代的疯狂
  11. python在d盘增加环境变量配置_怎样配置Python环境变量
  12. 利用史密斯圆图计算阻抗匹配网络的软件
  13. Windows Server 2008打印服务器安装与配置
  14. learning python in the hard way习题6~10的附加题练习
  15. QQ聊天自动刷屏视频课程-范浩浩-专题视频课程
  16. 技术支持程序员程序书写规范
  17. 计算机网络双语chapter4答案,计算机网络题库chapter4
  18. 湖北省潜江市谷歌高清卫星地图下载
  19. CSDN学霸课表——企业网络经典案例
  20. PMPBOK6之项目管理的33个文件

热门文章

  1. LeetCode(728)——自除数(JavaScript)
  2. LeetCode(977)——有序数组的平方(JavaScript)
  3. 【零基础学Java】—抽象方法和抽象类(二十二)
  4. HTML+CSS实现品优购登录界面
  5. 理财产品利息一直降低是什么原因?
  6. AdWords是什么
  7. 为什么有的工人喜欢午餐和晚餐配着一瓶啤酒?
  8. 在工作中你卑微到什么程度?
  9. 汽车上有哪些很难发现却非常实用的配置?
  10. “三步走”助你完成领导者转变