您的位置:首页 > 其它

利用宏简化配置文件读写的类

2009-03-12 14:55 501 查看
利用宏简化配置文件读写的类

作者:邓振波

代码下载:点击这里

应用程序编程过程中一般免不了需要读写配置文件。一般的做法是编写一个配置读写类。

比如需要读取和保存服务器的绑定地址和端口的配置

大致形式如下:

#define SectionServer "Server"

#define KeyPort "Port"

#define KeyAddress "Address"

class CAppConfig

{

int GetServePort()

{

return GetPrivateProfileInt(SectionServer , KeyPort, 80, m_strConfigFileName);

};

int GetServerAddress();

{

......

};

int SetServerPort(const int nPort);

{

......

};

int SetServerAddress(const char* pszAddr)

{

......

};

}

从上面看出,步骤一般如下:

1、为了方便的不写错段名和键名,一般会定义一批宏,代表段名和键名

2、写出GetXXX

3、写出SetXXX

有多个配置不断重复上面3个步骤,在配置多的情况下面,代码一大堆,写得很烦人。

如果我们能充分利用c++的宏、#和##的妙处,则可以把代码写得非常简单。

改造过的代码类似如下

class CAppConfig

{
public:

DEFINE_INT_CONFIG(Server, Port, 1);
DEFINE_STRING_CONFIG(Server, Address, "127.0.0.1");
};

通过一个宏,无需对段名和键名进行定义,同时生成了GetXXX和SetXXX的函数,同时还支持定义默认值。下面的全部代码。

#pragma once

//////////////////////////////////////////////////////////////////////////
//
//Created By Dengzhenbo
//Date: 2009-3-12
//
//////////////////////////////////////////////////////////////////////////

#include <string>
#include <assert.h>

#define GetConfigValueInt GetPrivateProfileIntA
#define GetConfigValueString GetPrivateProfileStringA
#define SetConfigValueString WritePrivateProfileStringA

#define DEFINE_INT_CONFIG(Section, Key, Default) /
int Get##Section##Key() /
{ /
return GetConfigValueInt(#Section, #Key, Default, m_strFileName.c_str()); /
}; /
int Set##Section##Key(int nValue) /
{ /
char szValue[20]; /
sprintf_s(szValue, sizeof(szValue), "%d", nValue); /
return SetConfigValueString(#Section, #Key, szValue, m_strFileName.c_str()); /
};

#define DEFINE_STRING_CONFIG(Section, Key, Default) /
std::string Get##Section##Key() /
{ /
int nRetCode = 0; /
char szValue[512] = {0}; /
std::string strReturn; /
GetConfigValueString(#Section, #Key, Default, szValue, sizeof(szValue), m_strFileName.c_str()); /
strReturn = szValue; /
return strReturn; /
}; /
int Set##Section##Key(char* szValue) /
{ /
return SetConfigValueString(#Section, #Key, szValue, m_strFileName.c_str()); /
};

class CConfigBase
{
public:

CConfigBase()
{
m_strFileName = "config.ini";
};

CConfigBase(const char* pszFilePath)
{
assert(pszFilePath);
m_strFileName = pszFilePath;
};

~CConfigBase(void){};

void SetConfigFilePath(const char* pszFilePath)
{
assert(pszFilePath);
m_strFileName = pszFilePath;
}

int GetConfigInt(const char* pszSection, const char* pszKey, int nDefaule)
{
return GetConfigValueInt(pszSection, pszKey, nDefaule, m_strFileName.c_str());
};

int SetConfigInt(const char* pszSection, const char* pszKey, int nValue)
{
char szValue[20];
sprintf_s(szValue, sizeof(szValue), "%d", nValue);
return SetConfigValueString(pszSection, pszKey, szValue, m_strFileName.c_str());
};

std::string GetConfigString(const char* pszSection, const char* pszKey, const char* pszDefaule) //String Value Max Length = 512
{
int nRetCode = 0;
char szValue[512] = {0};
std::string strReturn;
GetConfigValueString(pszSection, pszKey, pszDefaule, szValue, sizeof(szValue), m_strFileName.c_str());
strReturn = szValue;
return strReturn;
};

int SetConfigString(const char* pszSection, const char* pszKey, const char* pszValue)
{
return SetConfigValueString(pszSection, pszKey, pszValue, m_strFileName.c_str());
};

protected:

std::string m_strFileName;

};

使用的时候可以这样

class CAppConfig: public CConfigBase
{
public:

DEFINE_INT_CONFIG(Server, Port, 1);
DEFINE_STRING_CONFIG(Server, Address, "127.0.0.1");
};

上面代码展开宏后,会自动生成GetServerPort、SetServerPort、GetServerAddress和SetServerAddress函数,可以直接调用这4个函数。

呵呵,简单吧!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: