c++工程模式+配置文件+动态调用类

2023-11-19

前言

主函数

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Azure Java SDK:ServiceException:ForbiddenError:

    尝试了基本位置检索器代码 如下所示 String uri https management core windows net String subscriptionId XXXXXXXX 5fad XXXXXX 9dfa XXXXXX St
  • 从成员函数指针类型生成函子

    我正在尝试简化 通过make fn 预处理参数的函子的生成 通过wrap 对于 arity 的成员函数n 生成函子基本上可以工作 但到目前为止只能通过显式指定成员函数的参数类型来实现 现在我想从它处理的成员函数类型生成正确的函子 struc
  • 在 for 循环中访问 itertools 产品的元素

    我有一个列表列表 是附加 itertools 产品的一些其他结果的结果 我想要的是能够使用 for 循环访问列表列表中列表的每个元素 但我无法访问所有元素 我只能访问最后一个列表的元素 结果是一个非常巨大的列表列表 例如 1 2 4 3 6
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • 在 Java 中通过 D-Bus MPRIS 访问 Clementine 实例

    我使用 Clementine 作为音乐播放器 它可以通过 D Bus 命令进行控制 在命令行上 使用 qdbus 我可以 Start Stop 暂停播放器 强制它跳过播放列表中的歌曲 检查播放列表的长度 检查播放列表中当前播放的曲目及其元数
  • Python matplotlib:将轴标签/图例从粗体更改为常规粗细

    我正在尝试制作一些出版质量的图 但遇到了一个小问题 默认情况下 matplotlib 轴标签和图例条目的权重似乎比轴刻度线重 是否有办法强制轴标签 图例条目与刻度线的重量相同 import matplotlib pyplot as plt
  • Python RE(总之检查第一个字母是否区分大小写,其余部分不区分大小写)

    在下面的情况下 我想匹配字符串 Singapore 其中 S 应始终为大写 其余单词可能为小写或大写 但在下面的字符串 s 是小写的 它在搜索条件中匹配 任何人都可以让我知道如何实施吗 import re st Information in
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • 确定 JavaFX 中是否消耗了事件

    我正在尝试使用 JavaFX 中的事件处理来做一些非滑雪道的事情 我需要能够确定手动触发事件后是否已消耗该事件 在以下示例中 正确接收了合成鼠标事件 但调用 Consumer 不会更新该事件 我对此进行了调试 发现 JavaFX 实际上创建
  • 为什么要在 C++ 中使用 typedef?

    可以说我有 set
  • 带 getClassLoader 和不带 getClassLoader 的 getResourceAsStream 有什么区别?

    我想知道以下两者之间的区别 MyClass class getClassLoader getResourceAsStream path to my properties and MyClass class getResourceAsStre
  • 如何在supervisord中设置组?

    因此 我正在设置 Supervisord 并尝试控制多个进程 并且一切正常 现在我想设置一个组 以便我可以启动 停止不同的进程集 而不是全部或全无 这是我的配置文件的片段 group tapjoy programs tapjoy game1
  • ASP.NET JQuery AJAX POST 返回数据,但在 401 响应内

    我的应用程序中有一个网页 需要调用我设置的 Web 服务来返回对象列表 这个调用是这样设置的 document ready function var response ajax type POST contentType applicati
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • C 中带有指针的结构的内存开销[重复]

    这个问题在这里已经有答案了 我意识到当我的结构包含指针时 它们会产生内存开销 这里有一个例子 typedef struct int num1 int num2 myStruct1 typedef struct int p int num2
  • 为什么 Linux 对目录使用 getdents() 而不是 read()?

    我浏览 K R C 时注意到 为了读取目录中的条目 他们使用了 while read dp gt fd char dirbuf sizeof dirbuf sizeof dirbuf code Where dirbuf是系统特定的目录结构
  • C++、三元运算符、std::cout

    如何使用 C 用三元运算符编写以下条件 int condition1 condition2 condition3 int double result int or double std cout lt lt condition1 resul
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题
  • 设置 TreeSet 的大小

    有没有办法像数组一样对 Java 集合中的 TreeSet 进行大小限制 例如我们在数组中 anArray new int 10 数组具有固定长度 在创建数组时必须指定该长度 A TreeSet当您向其中添加元素时会自动增长 您无法设置其大
  • 关闭扫描仪是否会影响性能

    我正在解决一个竞争问题 在问题中 我正在使用扫描仪获取用户输入 这是 2 个代码段 一个关闭扫描器 一个不关闭扫描器 关闭扫描仪 import java util Scanner public class JImSelection publ

随机推荐