/********************************************************************
file name : const2buffer.h
author : Clark/陈泽丹
created : 2011-11-9
purpose : 提供常量"转"变量的适配器
*********************************************************************/
#pragma once
#include <tchar.h>
namespace CLK
{
//常量转变量
template<class T>
class const2buffer
{
public:
static const2buffer c2b(const T* _pConst, const int _iLen) throw(const TCHAR*)
{//结果用值传递比用局部,引用, 指针,静态传出结果的作法更具安全意义
try{ return const2buffer(_pConst, _iLen); }
catch(const TCHAR* pError){ throw pError; }
}
explicit const2buffer(const T* _pConst, const int _iLen) throw(const TCHAR*): m_pBuf(NULL)
{
init(_pConst, _iLen);
}
const2buffer(const const2buffer& other) throw(const TCHAR*):m_pBuf(NULL)
{//有内存操作,传参时需注意class objThis = other时出现浅拷贝问题
init(other.m_pBuf, other.m_iLen);
}
const2buffer& operator = (const const2buffer& other) throw(const TCHAR*)
{//有内存操作,传参时需注意objThis = other时出现浅拷贝问题
init(other.m_pBuf, other.m_iLen);
return *this;
}
~const2buffer()
{
uninit();
}
operator T*()
{
return m_pBuf;
}
operator T()
{
return m_pBuf[0];
}
private:
void init(const T* _pConst, const int _iLen)
{
uninit();
m_iLen = _iLen;
m_pBuf = new T[m_iLen+1];
if( NULL == m_pBuf)
{
TCHAR _tcsError[64];
_stprintf(_tcsError,_T("Failed in const2buffer::new[%d]\n"),m_iLen);
throw _tcsError;
}
memset(m_pBuf,0,(m_iLen+1)*sizeof(T));
memcpy(m_pBuf,_pConst,m_iLen*sizeof(T));
}
void uninit()
{
if( NULL != m_pBuf)
{
delete[] m_pBuf;
m_pBuf = NULL;
}
}
T* m_pBuf;
int m_iLen;
};
//单字节转双字节
class a2w
{
public:
explicit a2w():buffer(0){}
explicit a2w(const char* str) throw(const TCHAR*):buffer(0)
{
try { init(str); }
catch(const TCHAR* pError){ throw pError; }
}
a2w(a2w& other) throw(const TCHAR*):buffer(0)
{
try { *this = other; }
catch(const TCHAR* pError){ throw pError; }
}
void init(const char* str) throw(const TCHAR*)
{
if( NULL != buffer)
delete[] buffer;
if(NULL != str)
{
int nLen = ::MultiByteToWideChar(CP_ACP,0,str,-1,NULL,0);
buffer = new wchar_t[nLen+1];
if( NULL == buffer)
{
buffer = NULL;
TCHAR _tcsError[256];
_stprintf(_tcsError,_T("Failed in a2w -> init -> new wchar_t[%d]\n"),nLen+1);
throw _tcsError;
}
memset(buffer,0,(nLen+1)*sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP,0,str,-1,buffer,nLen);
buffer[nLen] = 0;
}
}
~a2w()
{
delete[] buffer;
}
a2w& operator=(a2w& other) throw(const TCHAR*)
{
if( NULL != buffer)
delete[] buffer;
if(NULL != other.buffer)
{
int nLen = wcslen(other.buffer);
buffer = new wchar_t[nLen+1];
if( NULL == buffer)
{
buffer = NULL;
TCHAR _tcsError[256];
_stprintf(_tcsError,_T("Failed in a2w::init -> new wchar_t[%d]\n"),nLen+1);
throw _tcsError;
}
memset(buffer,0,(nLen+1)*sizeof(wchar_t));
wcscpy(buffer,other.buffer);
buffer[nLen] = 0;
}
return *this;
}
operator const wchar_t*() { return buffer; }
private:
wchar_t* buffer;
};
//双字节转单字节
class w2a
{
public:
explicit w2a():buffer(0){}
explicit w2a(const wchar_t* str) throw(const TCHAR*):buffer(0)
{
try { init(str); }
catch(const TCHAR* pError){ throw pError; }
}
w2a(w2a& other) throw(const TCHAR*):buffer(0)
{
try { *this = other; }
catch(const TCHAR* pError){ throw pError; }
}
void init(const wchar_t* str) throw(const TCHAR*)
{
if( NULL != buffer)
delete[] buffer;
if(NULL != str)
{
int nLen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
buffer = new char[nLen+1];
if( NULL == buffer)
{
buffer = NULL;
TCHAR _tcsError[256];
_stprintf(_tcsError,_T("Failed in w2a::init -> new char[%d]\n"),nLen+1);
throw _tcsError;
}
memset(buffer,0,(nLen+1)*sizeof(char));
::WideCharToMultiByte (CP_ACP, 0,str, -1,buffer , nLen, NULL,NULL);
buffer[nLen] = 0;
}
}
~w2a() { delete[] buffer; }
w2a& operator=(w2a& other) throw(const TCHAR*)
{
if( NULL != buffer)
delete[] buffer;
if(NULL != other.buffer)
{
int nLen = strlen(other.buffer);
buffer = new char[nLen+1];
if( NULL == buffer)
{
buffer = NULL;
TCHAR _tcsError[256];
_stprintf(_tcsError,_T("Failed in w2a::init -> new char[%d]\n"),nLen+1);
throw _tcsError;
}
memset(buffer,0,(nLen+1)*sizeof(char));
strcpy(buffer,other.buffer);
buffer[nLen] = 0;
}
return *this;
}
operator const char*() { return buffer; }
private:
char *buffer;
};
}
//测试 ------------------------------
CLK::const2buffer<TCHAR> Test()
{
TCHAR szTemp[100];
_tcscpy(szTemp,L"123456789");
return CLK::const2buffer<TCHAR>(szTemp, _tcslen(szTemp));
}try
{
const int TEMP_SIZE = 100;
TCHAR tcsTemp[TEMP_SIZE];
_stprintf(tcsTemp,_T("char* = %s\n"), (TCHAR*)CLK::const2buffer<TCHAR>::c2b(L"123",_tcslen(L"123")));
MessageBox(tcsTemp);
_stprintf(tcsTemp,_T("int = %d\n"), (int)CLK::const2buffer<int>::c2b(&TEMP_SIZE,1));
MessageBox(tcsTemp);
MessageBox(Test());
}
catch (const TCHAR* e)
{
MessageBox(e);
}
//测试结果: 功能正常,无内存漏露
本文详细介绍了常量与变量之间的适配器类的设计与实现,包括单字节到双字节转换、双字节到单字节转换等关键功能,以及内存管理的细节,确保了代码的安全性和效率。
969

被折叠的 条评论
为什么被折叠?



