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

前言

主函数

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.html
https://edu.csdn.net/course/detail/8482

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352

推荐阅读更多精彩内容