• 简单的C++配置模块


      我到公司后接到的是之前的一个客户端的项目,在老版本基础上修改了个简单的界面引擎,最近把旧的业务也迁移了过来。旧的项目配置模块使用的是SQLite,经理发现那个升级不方便,让我把配置修改成普通配置文件的方式。

      把程序里面用到配置文件的地方整理了下,分为两类:

    1  参数类,简单来说类似(Key, Value)

    2 列表类,同数据库一样的多个域的一条条记录

      最先想到的是使用XML来做配置文件。第一类类似

    <Config>
    <Param key1=value1 key2=value2......./> 
    </Config>

    第二类的类似

    <Config>
    <Item field1=value1 field2=value2....../>
    .....
    </Config>

      项目已经使用的库有rapidxml,貌似仅能解析,且对UNICODE支持不好,我之前还对他作了少量修改才可以。几年前的项目还用到了Tinyxml,也仅支持Ansi字符串,也懒得去动它。

      反正用了各种途径没有发现好用的C++的XML模块,于是打算自己写个简单的读写配置文件的模块。最基本的想法是简单,可用,就想到了Lua, Javascript的表示方法

    第一类的类似

    {
    key1:value1,
    key2:value2,
    ......
    }

    第二类的类似

    [
    {field1:value1, field2:value2,...},
    ...
    ]

    下面是代码关键片段,不包含Parser.

    namespace Config
    {
      enum Type{TYPE_NULL, TYPE_TABLE, TYPE_ARRAY, TYPE_TEXT, TYPE_NUMBER};
      class Object
      {
      public:
        Object(Type type);
        ~Object();

        Object(const Object& obj);
        Object& operator=(const Object& obj);

       Type GetType();

        //表和数组的操作
    Object& operator[](const std::wstring&);
    Object& operator[](int index);
    int GetCount();
        int Contains(const std::wstring&);
        //数组的更多操作

    //数字和文本的操作
        int GetNumber();
        void SetNumber(int number);


        std::wstring GetText();
    void SetText(const std::wstring&);

      protected:
        struct InnerObject()
        {
          InnerObject(Type type);
          ~InnerObject();
          
          void AddRef();
          void DecRef();

          Type m_Type;
    int m_iReferenceCount;
          
          union
          {
            std::vector<Object>* m_arrObjects;
            std::map<std::wstring, Object>* m_tblObjects;
            std::wstring* m_sText;
            int m_iNumber;
          }
        }*m_pInnerObject;
      };
    }

    为甚么要把几种数据操作糅合在一起看上去很奇特,这是经过仔细思考了的。如果不放在一起必然使用指针啊,类型强制转换之类的操作起来更不方便。

    现在只需要用GetType(),再调用匹配的函数操作即可,并且对象内部使用计数管理,可以像使用值对象一样来使用,不用自己来进行内存管理。

    代码段的接口都有了,实现起来就很简单了,代码也不太长。

    目前也只写了个大概,可能还有点问题。

    使用举例:

    int main()
    {
      Config::Object obj = Parse(L"{a:5,b:[{x:3,y:4,name:\"a\"},
    {x:3,y:4,name:\"a\"}],c:\"aaa\"}");

    //读取
    std::wstring name = obj[L"b"][1][L"name"].GetText();
    //修改
    obj[L"b"][0][L"y"].SetNumber(8);


      return 0;
    }

    大概意思就这样,Object可以多重载几个构造函数,初始化的时候直接赋值。

  • 相关阅读:
    洛谷 P2260 [清华集训2012]模积和 || bzoj2956
    Mass Change Queries Codeforces
    Single-use Stones Codeforces
    洛谷 P4503 [CTSC2014]企鹅QQ
    洛谷 P1463 [HAOI2007]反素数
    Bear and Tower of Cubes Codeforces
    洛谷 P1593 因子和 || Sumdiv POJ
    记一次服务器inodes数报警的事件
    MySQL参数详解
    Django基础流程
  • 原文地址:https://www.cnblogs.com/cmzbjl/p/3080843.html
Copyright © 2020-2023  润新知