前言

主函数

SimpleFactoryRefactor.cpp

#include <iostream>
#include<string>
#include "DynOBJ.h"
#include "get_config.h"
using namespace std;
#define CFG_FILE_PATH "test.cfg"class Api {
public:virtual void test(string) = 0;
protected:Api(){}
};class ImpleOne :public Api {
public:void test(string s){cout << "现在是One在执行" << s;}
};class ImpleTwo :public Api {
public:void test(string s){cout << "现在是Two在执行" << s;}
};REG_CLASS(ImpleTwo)
REG_CLASS(ImpleOne)class ConfigOperator{
public:ConfigOperator(string path){ this->cfgPath = path;//-----------------------------通过cfg文件中的配置信息,来确定代码运行那一部分下//----------------------------读取配置文件,确定运行内容,↓map<string, string> m;ReadConfig(CFG_FILE_PATH, m);/**************************读取配置文件↑***************************///PrintConfig(m);//——————————————解析内容(1)获得参数个数(2)获得参数值下Numb = m.find("AddClassNumb")->second;//找到的是key,那么它的下一个就是value了Class = m.find("ClassFirst")->second;//};~ConfigOperator(){};string GetOperatorClassName(){ return this->Class; };private: string cfgPath;string  Numb;string  Class;};class AutoFactory{
public:static Api* createApi(){string OperatorClassName;//获得配置文件的运行操作内容ConfigOperator* cfgOp = new ConfigOperator(CFG_FILE_PATH);OperatorClassName = cfgOp->GetOperatorClassName();//-----------------------------运行完全高层、抽象的内容↓Api *pApi = nullptr;pApi = static_cast<Api*>(CObjectFactory::creatObject(OperatorClassName));return pApi;}
};int main(void)
{ Api* pApi = AutoFactory::createApi(); pApi->test("完全实现客户端的分离!即,调用者和实际工作者的划分");system("pause");return 0;
}//--------------代码运行中的不同阶段//class ImpleTwoHelper
//{
//public:
//  ImpleTwoHelper(){
//      CObjectFactory::registerClass("ImpleTwo", ImpleTwoHelper::createObjFunc);
//
//  }
//  static void *createObjFunc(){
//      return new ImpleTwo;
//  }
//};
//int main2(void)
//{
//  ImpleTwo*pTwo = static_cast<ImpleTwo*>(ImpleTwoHelper::createObjFunc());
//
//  pTwo->test("测试动态创建Two!");
//  system("pause");
//  return 0;
//}
//int main1(void)
//{
//  ImpleOne* pOne = static_cast<ImpleOne*>(CObjectFactory::creatObject("ImpleOne"));
//
//  pOne->test("RegClass");
//  system("pause");
//  return 0;
//}

DynOBJ.h

#ifndef DYNOBJ_H_
#define DYNOBJ_H_
#include<string>
#include<map>
typedef void*(*Constructor)();
class CObjectFactory{
public:static void registerClass(std::string className, Constructor constructor)   {constructors()[className] = constructor;}static void* creatObject(const std::string& className) {Constructor constructor = NULL;if (constructors().find(className) != constructors().end())//查找map中key为classname的一个元素,如果找到了{constructor = constructors().find(className)->second;//找到的是key,那么它的下一个就是value了}if (constructor == NULL){return NULL;}return(*constructor)();}
private://string->key:动态创建的类的类名,value是构建inline static std::map<std::string,Constructor>&constructors(){static std::map<std::string,Constructor> instance;return instance;}
};#define REG_CLASS(class_name)\
class class_name##Helper\
{\
public:\class_name##Helper(){\CObjectFactory::registerClass(#class_name, class_name##Helper::createObjFunc);\}\static void *createObjFunc(){\return new class_name;\}\
};\
class_name##Helper class_name##helper;\//#define REG_CLASS(class_name) \
//class class_name##Helper\
//{\
//public:\
//  class_name##Helper(){\
//      CObjectFactory::registerClass(#class_name,  class_name##Helper::createObjFunc);\
//  };\
//  static void* createObjFunc(){\
//      return new class_name;\
//  };\
//};\
//class_name##Helper class_name##Helper;\#endif // !DYNOBJ_H_
//
//class ImpleOneHelper{ public: ImpleOneHelper(){ CObjectFactory::registerClass("ImpleOne", ImpleOneHelper::createObjFunc); }; static void* create0bjFunc(){ return new ImpleOne; }; }; ImpleOneHelper ImpleOneHelper;
/****************************************************************************
*   作者:  董康乐
*   日期:  2022年1月23日14:59:24
*   目的:  读取配置文件的信息,以map的形式存入
*   要求:  配置文件的格式,以#作为行注释,配置的形式是key = value,中间可有空格,也可没有空格
*****************************************************************************/
#ifndef _GET_CONFIG_H_
#define _GET_CONFIG_H_#include <string>
#include <map>
using namespace std;#define COMMENT_CHAR '#'bool ReadConfig(const string & filename, map<string, string> & m);
void PrintConfig(const map<string, string> & m);
#endif
#include "get_config.h"#include <fstream>
#include <iostream>
using namespace std;bool IsSpace(char c)
{if (' ' == c || '\t' == c)return true;return false;
}bool IsCommentChar(char c)
{switch (c) {case COMMENT_CHAR:return true;default:return false;}
}void Trim(string & str)
{if (str.empty()) {return;}int i, start_pos, end_pos;for (i = 0; i < str.size(); ++i) {if (!IsSpace(str[i])) {break;}}if (i == str.size()) { // 全部是空白字符串str = "";return;}start_pos = i;for (i = str.size() - 1; i >= 0; --i) {if (!IsSpace(str[i])) {break;}}end_pos = i;str = str.substr(start_pos, end_pos - start_pos + 1);
}bool AnalyseLine(const string & line, string & key, string & value)
{if (line.empty())return false;int start_pos = 0, end_pos = line.size() - 1, pos;if ((pos = line.find(COMMENT_CHAR)) != -1) {if (0 == pos) {  // 行的第一个字符就是注释字符return false;}end_pos = pos - 1;}string new_line = line.substr(start_pos, start_pos + 1 - end_pos);  // 预处理,删除注释部分if ((pos = new_line.find('=')) == -1)return false;  // 没有=号key = new_line.substr(0, pos);value = new_line.substr(pos + 1, end_pos + 1 - (pos + 1));Trim(key);if (key.empty()) {return false;}Trim(value);return true;
}bool ReadConfig(const string & filename, map<string, string> & m)
{m.clear();ifstream infile(filename.c_str());if (!infile) {cout << "file open error" << endl;return false;}string line, key, value;while (getline(infile, line)) {if (AnalyseLine(line, key, value)) {m[key] = value;}}infile.close();return true;
}void PrintConfig(const map<string, string> & m)
{map<string, string>::const_iterator mite = m.begin();for (; mite != m.end(); ++mite) {cout << mite->first << "=" << mite->second << endl;}
}

配置文件格式:test.cfg

AddClassNumb = 2
ClassFirst  =    ImpleTwo
ClassSecond  =    ImpleTwo
#sdf

参考文献

工厂模式https://blog.csdn.net/a844651990/article/details/84392410配置文件配置文件https://www.cnblogs.com/shanlizi/p/6912976.htmlhttps://edu.csdn.net/course/detail/8482


http://www.taodudu.cc/news/show-1639462.html

相关文章:

  • 读书感悟之,从术到道
  • 因果否?
  • (01)数据库及相关
  • avg最多用多少列 mysql_40斤一桶水,最多用多少克磷酸二氢钾?打几次增产效果最好...
  • 用单片机测量流体流速的_旋进旋涡流量计的测量原理及优点
  • 文字加减前后缀lisp_日本搞笑艺人催泪讲授汉字课堂告诉你文字背后的意义!...
  • 幼儿园调查过程怎么写_幼儿园对孩子的重要性你真的清楚吗?
  • 三星oneui主屏幕费电_这或许是单手握持手感最佳的手机 三星Galaxy S20上手体验...
  • 麦克纳姆轮运动原理怎么安装_家用中央空调水系统原理是什么?怎么样安装比较好呢?...
  • redis 判断存在性_一口气说出四种幂等性解决方案,面试官露出了姨母笑~
  • python心跳包原理_Python 用心跳(UDP包)探测不活动主机
  • pin码计算器网页版_快对作业APP下载手机版电脑版官方正式上线
  • 进入已经打开的pyrebox_PyREBox-可用Python编写脚本的逆向工程沙盒
  • idea redis图形化_5.13redis图形化工具---idea中配置redis密码
  • oem718d 基准站设置_诺瓦泰NovAtel OEM718D全系统多频单机测向板卡
  • 常见的预设分栏包括_计算机应用基础_实训项目二Word综合应用
  • 嵌入式linux系统移植的四大步骤_嵌入式 Linux 产品技术评估之系统裁剪与启动速度...
  • centos 卸载_9个Linux发行版本,教你如何分别使用命令行卸载安装包
  • java foreach多线程_详解多线程入门案例与java8的并行流
  • console线驱动安装_低压灯带和高压灯带区别是啥 安装方法是啥?
  • @entity 不限字节长度的类型_面试常考,项目易错,长文详解C/C++中的字节对齐...
  • 有没有安卓4.0的java模拟器_电脑端安装Android4.0模拟器使用教程
  • (带区号)座机号正则_字符串处理之正则表达式(通俗易懂)
  • correl函数_函数中的“豪门贵族”【统计函数】
  • 大数据工程师简历_大数据工程师简历范本02
  • 人之间的尊重是相互的_人与人之间,尊重很重要
  • 以前是传xml的吗_李菲儿参加《浪姐2》,与黄晓明同台互动!不怕baby吃醋吗?...
  • 网优5g前景_网优行业的吐槽,附吐槽记录
  • java生成txt_Java ThreadDump 生成解析
  • mac模式怎样构造在jsp中_在MAC下搭建JSP开发环境

c++工程模式+配置文件+动态调用类相关推荐

  1. (C#)利用反射动态调用类成员[转载]

    使用反射动态调用类成员,需要Type类的一个方法:InvokeMember.对该方法的声明如下(摘抄于MSDN): public object InvokeMember(    string name ...

  2. 利用反射动态调用类成员C#

    使用反射动态调用类成员,需要Type类的一个方法:InvokeMember.对该方法的声明如下(摘抄于MSDN): public object InvokeMember(    string name ...

  3. C# 利用反射动态调用类成员

    使用反射动态调用类成员,需要Type类的一个方法:InvokeMember.对该方法的声明如下: public object InvokeMember( string name, BindingFla ...

  4. 动态调用类 java_Java动态调用类中方法

    在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方 ...

  5. HTTP 调用 WebService、CXF 动态调用 WebService

    概述   Web Service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配置这些应用程序,用 ...

  6. python调用函数示例_python 动态调用函数实例解析

    1. 根据字符串名称 动态调用 python文件内的方法eval("function_name")(参数) 2. 根据字符串 动态调用类中的静态方法,getattr(ClassNa ...

  7. SpringMVC几个核心类(控制器核心类,加载配置文件核心类,处理url影射核心类,处理视图资源核心类,方法动态调用核心类)

    核心类 制器核心类: •org.springframework.web.servlet.DispatcherServlet  - 配置web.xml   加载配置文件核心类: •org.springf ...

  8. C++ DLL总结—静动态调用、导出类

    1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别: (1)静态链接库与 ...

  9. Eval.cs的改进版 动态编译类,可以计算表达式,也可以调用系统中的类

    Eval.cs的改进版 动态编译类,可以计算表达式,也可以调用系统中的类 /* 动态编译类,可以计算表达式,也可以调用系统中的类 调用方式:     return new XXXXXXX.Eval() ...

最新文章

  1. mysql内存爆_线上MySQL机器内存爆掉原因分析与解决
  2. 主瓣,旁瓣,栅瓣概念解析
  3. redirect-action
  4. 1000多首无损歌曲合集
  5. 9名程序员被抓!这次我并不同情他们!
  6. qt glsl渲染rgb
  7. 美国确诊超46万!美国州长竟然抢起高龄程序员了,什么情况?
  8. Python Imaging Library: ImageFilter Module(图像滤波模块)
  9. C#語法學習二(NameSpace)
  10. mitProxy下载和使用
  11. Docker命令(二)
  12. 深度残差网络+自适应参数化ReLU激活函数(调参记录2)
  13. Word目录制作修改
  14. erlang ets写入mysql_ets:i/0 – 在输出端上打印显示所有 ETS 表的信息 - Erlang 中文手册...
  15. $splay$学习总结$QwQ$
  16. xpath prase string
  17. 个人微信公众号——定位策略
  18. 【荐】联通域名纠错 联通域名DNS劫持 您输入的域名有误或站点访问失败
  19. View 中 setVisibility(View.GONE); 失效
  20. liunx下关于图片、视频截图的处理

热门文章

  1. [PyTorch] 保存模型和恢复模型
  2. Airflow集成在线编写创建dag的插件
  3. AD16从两层切到显示一层的视图shift+s
  4. python接口自动化测试二十二:文件下载
  5. DWR第四篇之对象传参
  6. CodeForces - 556C Case of Matryoshkas
  7. Paypal Rest Api自定义物流地址(跳过填写物流地址)
  8. layout_weight
  9. asp.net 导出word文档
  10. [转载] python numpy 总结