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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rexinx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值