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++工程模式+配置文件+动态调用类 的相关文章

  • Python 3 中“map”类型的对象没有 len()

    我在使用 Python 3 时遇到问题 我得到了 Python 2 7 代码 目前我正在尝试更新它 我收到错误 类型错误 map 类型的对象没有 len 在这部分 str len seed candidates 在我像这样初始化它之前 se
  • 从 pygame 获取 numpy 数组

    我想通过 python 访问我的网络摄像头 不幸的是 由于网络摄像头的原因 openCV 无法工作 Pygame camera 使用以下代码就像魅力一样 from pygame import camera display camera in
  • 测试弱引用

    在 Java 中测试弱引用的正确方法是什么 我最初的想法是执行以下操作 public class WeakReferenceTest public class Target private String value public Targe
  • Cucumber Java 与 Spring Boot 集成 - Spring @Autowired 抛出 NullPointer 异常

    我正在为 Spring boot 应用程序编写 cucumber java 单元测试来测试每个功能 当我与 Spring Boot 集成时 Autowired 类抛出 NullPointer 异常 Spring Boot应用程序类 Spri
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • VSCode:调试配置中的 Python 路径无效

    对 Python 和 VSCode 以及 stackoverflow 非常陌生 直到最近 我已经使用了大约 3 个月 一切都很好 当尝试在调试器中运行任何基本的 Python 程序时 弹出窗口The Python path in your
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • glpk.LPX 向后兼容性?

    较新版本的glpk没有LPXapi 旧包需要它 我如何使用旧包 例如COBRA http opencobra sourceforge net openCOBRA Welcome html 与较新版本的glpk 注意COBRA适用于 MATL
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • 如何使用google colab在jupyter笔记本中显示GIF?

    我正在使用 google colab 想嵌入一个 gif 有谁知道如何做到这一点 我正在使用下面的代码 它并没有在笔记本中为 gif 制作动画 我希望笔记本是交互式的 这样人们就可以看到代码的动画效果 而无需运行它 我发现很多方法在 Goo
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • hashcode 的默认实现为以相同方式构造的对象返回不同的值

    我在这里编写一个示例代码 public class Test private int i private int j public Test TODO Auto generated constructor stub public Test
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • ServletContainer 类未找到异常

    我无法再编译我的球衣项目 并且出现以下异常 GRAVE Servlet Project API threw load exception java lang ClassNotFoundException com sun jersey spi
  • Python 分析:“‘select.poll’对象的‘poll’方法”是什么?

    我已经使用 python 分析了我的 python 代码cProfile模块并得到以下结果 ncalls tottime percall cumtime percall filename lineno function 13937860 9
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么

随机推荐