zoukankan      html  css  js  c++  java
  • 简单的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可以多重载几个构造函数,初始化的时候直接赋值。

  • 相关阅读:
    yocto/bitbake 学习资源
    QEMU/KVM学习资源
    ubuntu 中创建和删除用户
    git 重命名本地和远程分支
    Ubuntu 上搭建 FTP 服务器
    gdb 常见用法
    git log 显示与特定文件相关的 commit 信息
    基于 qemu system mode 运行 arm 程序
    基于 qemu user mode 运行 aarch64 程序
    checking in(airport)
  • 原文地址:https://www.cnblogs.com/cmzbjl/p/3080843.html
Copyright © 2011-2022 走看看