在最近的项目中,使用的插件式架构, 插件的每个功能都需要用户输入的参数(所需的参数值配置在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