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可以多重载几个构造函数,初始化的时候直接赋值。

  • 相关阅读:
    SQL JOIN
    string.Empty, "" 和 null 三者的区别
    java JDBC
    java 自定义注解
    Spring Bean自动检测
    Spring Aware接口
    IObservable 接口
    CloseHandle()函数的使用
    [置顶] 记一次讲座与前辈的对话
    让用户关上门说话:覆盖全美6000个社区的邻居私密社交网站Nextdoor是如何壮大的?
  • 原文地址:https://www.cnblogs.com/cmzbjl/p/3080843.html
Copyright © 2011-2022 走看看