标签:
在最近的项目中,使用的插件式架构, 插件的每个功能都需要用户输入的参数(所需的参数值配置在xml文件中),之前的做法是将每个功能需要的所有参数定义成结构体
程序一开始,解析XML文件,将对应名称的参数值填充到相应的字段中。如果参数个数很多,则参数结构体的字段就会很多,写起来就会很麻烦,而且当
某个模块新增参数时(在xml文件中添加),就必须修改参数结构体,不利于程序扩展。
所以写了一个下面的参数类,将xml中所有参数按 参数名(string) 参数值(string)键值对的形式存储到map中,当需要某个参数时,按参数名称
提取即可(且不区分参数名的大小写),使用者自己控制将参数解析成什么形式(整型,浮点型等) ,而且新增某个参数时,只需在xml按照一定的规则添加即可(参数名 参数值),不需要修改参数类。用的时候直接按名称提取即可。
记录如下:
参数配置XML文件格式简化为:
<Params> <Item Name="NetWorkType" Value="UMTS"></Item> <Item Name="GridCntThreshold" Value="100"></Item> </Params>
参数类如下:
param.h
#ifndef PARAM_H_ #define PARAM_H_ #include <map> #include <string> #include <algorithm> #include <sstream> using std::map; using std::string; using std::stringstream; //参数类 class CParam { public: struct NoCaseCompare { bool operator()(const string & str1, const string & str2) { string upper_str1(str1); string upper_str2(str2); std::transform(upper_str1.begin(),upper_str1.end(),upper_str1.begin(),toupper); std::transform(upper_str2.begin(),upper_str2.end(),upper_str2.begin(),toupper); return upper_str1.compare(upper_str2) >= 0 ? false : true; } }; typedef map<string,string,NoCaseCompare> StrMap; CParam(); virtual ~CParam(); //设置参数值 template <typename T> void SetParam(const string & param_name, const T & param_val); //得到double型参数 double GetParamDouble(const string & param_name); //得到整型参数值 int GetParamInt(const string & param_name); //得到字符串参数值 string GetParamString(const string & param_name); //得到bool型参数值 bool GetParamBool(const string & param_name); //加载参数配置文件,将所有参数按 参数名(string)-> 值(string) 的形式存储 bool LoadParamXml(const string & param_file_path); //清除所有参数 void Clear(); private: const char* FindParam(const string & param_name); private: StrMap _params; }; template <typename T> void CParam::SetParam(const string & param_name, const T & param_val) { stringstream ss; ss << param_val; _params[param_name] = ss.str(); } #endif
param.cpp
#define TIXML_USE_STL #include "param.h" #include <tinyxml.h> CParam::CParam() { } CParam::~CParam() { } double CParam::GetParamDouble( const string & param_name ) { double val = 0; const char * pStr = this->FindParam(param_name); if (NULL != pStr) { val = atof(pStr); } return val; } const char * CParam::FindParam(const string & param_name) { StrMap::const_iterator it = _params.find(param_name); if (it != _params.end()) { return it->second.c_str(); } return NULL; } int CParam::GetParamInt( const string & param_name ) { int val = 0; const char * pStr = FindParam(param_name); if (NULL != pStr) { val = atoi(pStr); } return val; } string CParam::GetParamString( const string & param_name ) { StrMap::const_iterator it = _params.find(param_name); if (it != _params.end()) { return it->second; } return ""; } bool CParam::GetParamBool( const string & param_name ) { bool val = false; const char * pStr = FindParam(param_name); if (NULL != pStr) { string str(pStr); std::transform(str.begin(),str.end(),str.begin(),tolower); if (str == "t" || str == "true" || atoi(str.c_str()) > 0) { val = true; } } return val; } bool CParam::LoadParamXml( const string & param_file_path ) { //从参数 配置文件中读取所有参数 TiXmlDocument doc; if (!doc.LoadFile(param_file_path)) { return false; } TiXmlHandle handle(&doc); TiXmlElement *pChild = handle.FirstChild("Params").FirstChild("Item").Element(); for (; NULL != pChild; pChild = pChild->NextSiblingElement()) { string name; string val; pChild->QueryStringAttribute("Name",&name); pChild->QueryStringAttribute("Value",&val); this->SetParam(name,val); } return true; } void CParam::Clear() { _params.clear(); }
测试代码如下:
CParam param; param.LoadParamXml("d:\\TEST\\Param.xml"); cout << param.GetParamDouble("GridCntThreshold") << endl; cout << param.GetParamString("NETWORKTYPE") << endl;
标签:
原文地址:http://www.cnblogs.com/cmranger/p/4379571.html