C++实现类似反射模式(模板)

编程技巧 2010-11-23 21:08:02 阅读70 评论0   字号:大小 订阅

最近在编写遥感算法工具箱的时候,工具都是在xml文件中配置好的,在工具箱上构建一棵树根据xml配置文件,然后通过双击不同的树节点,弹出不同的算法对话框。最简单的方式就是使用if else 或者switch case之类的条件判断语句来实现,但是这个太不方便了,每增加一个算法,都要在分支上添加一个条件判断,用现在流行的话说就是太不给力了。于是想通过一个比较通用的方式来解决这个问题。

由于我的算法对话框都是基于MFC的CDialog,所以可以通过算法对话框的类名来创建各自的对象,然后将对话框显示。以前知道在Java和C#中有一个反射模式,就是可以通过类名来创建一个类的对象。但是C++是没有这个东东的,于是就查找资料,终于用C++的模板实现了类似的功能。下面贴代码:
/***************************************************************************
*
* Time: 2010-11-23
* Project: 遥感平台 
* Purpose: 图像数据处理对话框反射模式
* Author:  李民录
* Copyright (c) 2010, LT_IMAGE
*
****************************************************************************/
/** /file RegistClassName.h 
* 图像数据处理对话框反射模式
*/
#ifndef REGISTCLASSNAME_H
#define REGISTCLASSNAME_H
#include <afxwin.h>
#include <map>
#include <string>
using namespace std;
#ifdef _DEBUG
#include <assert.h>
#endif
/**
* @brief 重定义对象
*/
typedef CDialog*(*pf)();
/**
* /class ClassMap RegistClassName.h 
* @brief 类映射
*/
class ClassMap
{
private:
/**
* @brief 私有构造函数
* 为了让这个类不产生实例对象
*/
ClassMap() { }
/**
* @brief 以类名为键的一个存放着构建方法的Hash表
*/
static map<string, pf> m_ClassMap;
public:
/**
* @brief 定义一个类必须注册一下
* @param _className 类名
* @param _createFun 注册函数指针
*/
static void RegistClass(string _className, pf _createFun)
{
if(m_ClassMap.find(_className) != m_ClassMap.end())
return; //已经注册过,直接返回
m_ClassMap[_className] = _createFun;
}
/**
* @brief 私有构造函数
* @param _className 类名
*/
static CDialog* forName(string _className)
{
if(m_ClassMap.find(_className) == m_ClassMap.end())
{
#ifdef _DEBUG
assert(0);
#endif
return NULL; //没有找到类对象,返回NULL
}
return (m_ClassMap[_className])();
}
};
/**
* @brief 以类名为键的一个存放着构建方法的Hash表
* 此处一定要注意在前面添加__declspec(selectany) ,否则编译时提示符号重定义
*/
__declspec(selectany) map<string, pf> ClassMap::m_ClassMap;
/**
* /class DelegatingObject RegistClassName.h 
* @brief 委派模板类
*/
template<typename T>
class DelegatingObject 
{
public:
/**
* @brief 构造函数
* @param _className 类名
*/
DelegatingObject(string _className)
{
ClassMap::RegistClass(_className, &(DelegatingObject::Create));
}
/**
* @brief 创建实例函数
*/
static CDialog* Create()
{
return static_cast<CDialog*>(new T);
}
};
/**
* @brief 注册类的宏定义
*/
#ifndef REGIST_CLASS
#define REGIST_CLASS(X) DelegatingObject<X> __class_##X( #X );
#endif
#endif //REGISTCLASSNAME_H

这样只要在各自的算法对话框的Cpp文件前面添加下面一句话即可:
REGIST_CLASS(CRasterTransformDlg); //栅格文件格式转换
REGIST_CLASS(CVectorTransformDlg); //矢量文件格式转换
然后在调用算法的地方按照下面使用方法即可,这样就不用写一大批的if或者switch语句了:
BOOL ShowAlgoDialog(string strDlgName) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CDialog * pDlg = (ClassMap::forName(strDlgName)); if(pDlg == NULL) { AfxMessageBox("该类没有注册,请检查!",MB_OK); return FALSE; } else { pDlg->DoModal(); } return TRUE;
}

C++实现类似反射模式(模板)相关推荐

  1. C++实现类似反射模式

    在编写遥感算法工具箱的时候,工具都是在xml文件中配置好的,在工具箱上构建一棵树根据xml配置文件,然后通过双击不同的树节点,弹出不同的算法对话框.最简单的方式就是使用if else 或者switch ...

  2. 模板模式详解、模板模式怎么用、模板模式模板代码

    模板模式详解.模板模式怎么用.模板模式模板代码 文章目录 模板模式详解.模板模式怎么用.模板模式模板代码 @[toc] 模板模式定义 使用场景 优点 代码实操 模板模式定义 在模板模式(Templat ...

  3. 设计模式之策略模式+工厂模式+模板模式结合

    设计模式之策略模式+模板模式 为什么总是学不好设计模式 从"登录功能"中发现问题. 首先我们简单的了解功能需求: 于是你开始干活了: 1.控制层代码如下,根据不同的登录方式调用不同 ...

  4. 反射模式python

    百科定义: 在计算机学中,反射式编程(英语:reflective programming)或反射(英语:reflection),是指计算机程序在运行时(runtime)可以访问.检测和修改它本身状态或 ...

  5. 2019CAD设置经典模式模板详细步骤

    2019CAD设置经典模式步骤 第一步:下载经典模式模板 链接:https://pan.baidu.com/s/1Wyt0SQxqOG1nETg55rHq-w 提取码:lpxq 第二步:安装 1 2打 ...

  6. java反射出抽象类的实现类_java利用反射模式调用实现类

    本文主讲,java利用反射模式调用接口的实现类.抽象类的继承子类.下面请听一一道来 1.第一步在src下创建com.newer.reflex包 2.在com.newer.reflex包下面建立IRef ...

  7. JAVA利用反射模式调用实现类

    本文主讲,利用反射模式调用接口的实现类.抽象类的继承子类.下面请听屌丝一一道来 1.第一步在src下创建 com.newer.reflex包 2.在com.newer.reflex包下面建立 IRef ...

  8. 类似滴滴打车模式搬家预约抢单系统开发

    类似滴滴打车模式搬家预约抢单系统开发找小凡团队 158.1500.1390 微or电,搬家预约抢单系统开发.搬家预约抢单功能开发,搬家预约抢单软件开发. 在我们的生活中,常常会碰到需要搬运大件的家具或 ...

  9. Java设计模式之策略模式+工厂模式+模板模式

    Java设计模式之策略模式+工厂模式+模板模式 1.策略模式+工厂模式+模板模式 个人的理解:实际开发工程中,一些业务很复杂的逻辑使用很多的 if 或者 if···else 语句,不利于维护和扩展,为 ...

最新文章

  1. Android进阶笔记07:Android之MVC 理解
  2. 计算机网络最提出的优点是什么,2013年计算机一级B考试模拟试题十八及答案解析...
  3. python怎么导入包-如何理解Python中包的引入
  4. Column 'Status' in where clause is ambiguous
  5. MYSQL 表锁情况查看
  6. 步进电机无细分和20细分_细分网站导航会话
  7. php多维求组按照健值排序,PHP编程实现多维数组按照某个键值排序的方法小结【2种方法】...
  8. Markdown笔记神器Typora配置Gitee图床
  9. 玛雅三维动画制作Maya 2022 for Mac
  10. 注意!思科Aironet 1830和1850系列存在硬编码密码,请尽快修复!
  11. 第2次作业:微博软件分析
  12. Spring5,最全教程,带你认识IOC容器和AOP切面
  13. Netty自定义数据包
  14. Android 不透明度值换算
  15. 基于ARM处理器的TSC2046触摸屏控制器的应用
  16. STM32基于 FatFs R0.14bSD Card 的MP3音乐播放器(也算是FatFs的简单应用了吧)
  17. 服务器里面增加单页网站,单页网站:搜索引擎的最爱
  18. 利用dlib81人脸关键点提取额头脸颊ROI
  19. vue中this.$confirm,确定和取消执行不同的逻辑处理
  20. 义乌个体户可以收美金安全吗?

热门文章

  1. Java_Object类
  2. [导入]在ASP.NET中跨页面实现多选
  3. hdu 4529(状态dp)
  4. spring核心之IOC
  5. CSS DIV Shadow
  6. Lucene搜索引擎例子demo
  7. js操作DOM对象(节点的增删改)
  8. 基于vue的颜色选择器vue-color-picker
  9. 移动设备真机调试本地程序的Node.js【无需连wifi】
  10. php怎么返回json格式的数据