ADO防止內存泄露和減少內存開銷的方法
作者:boqing
(自己琢磨的,如果您發現不當之處,望不吝賜教)
導讀:經常碰到在一個工程中的幾個類中都需要調用數據庫,因此可考慮編寫一個數據庫管理類來實現基本的問題,防止內存泄露與不必要的內存開銷的幾個需要注意的事情:1)CreateInstance後不要忘記Release;2)Open後不要忘記Close;3)儘量保證數據管理類只有一個實例。
(一)建立一個數據管理類CDataMange,本類只能創建一個實例,具體方法:
l 創建成員變量,私有,靜態
private:
static CDataMange *m_pStatic;
l 在實現文件(*.cpp)中初始化m_pStatic變量
CDataMange *CDataMange::m_pStatic=NULL;
l 創建成員函數,得到m_pStatic。共有,靜態
public:
static CWEMange * getInstancePtr(void);
l 實現getInstancePtr函數
CWEMange * CWEMange::getInstancePtr(void)
{
if (m_pStatic==NULL)
m_pStatic=new CWEMange();
return m_pStatic;
}
(二)在CDataMange類中創建成員
_ConnectionPtr p_Con;
_RecordsetPtr p_Record;
_CommandPtr p_Com;
(三)構造函數中初始化
CDataMange::CDataMange(void)
{
HRESULT hr;//0代表成功返回
hr = p_Con.CreateInstance(__uuidof(Connection));
if (SUCCEEDED(hr))
AfxMessageBox(_T("初始化p_Con失敗"));
hr=p_Record.CreateInstance(__uuidof(Recordset));
if (!SUCCEEDED(hr))
AfxMessageBox(_T("初始化p_Record失敗"));
……
}
(四)編寫一個查詢函數
注意:打開記錄集後不要忘記關閉
std::vector<CString> CDataMange::getClass(void)
{
std::vector<CString> str_class;
_variant_t vtemp;
try
{
p_Record->Open("Class",_variant_t((IDispatch*)p_Con),adOpenStatic,adLockOptimistic,adCmdTable);
if (p_Record->adoEOF)
AfxMessageBox(_T("Class無數據"));
for(p_Record->MoveFirst();!p_Record->adoEOF;p_Record->MoveNext())
{
vtemp=p_Record->Fields->Item["class_name"]->Value;
str_class.push_back(vtemp.bstrVal);
}
}
catch (...)
{
CWEMange::getInstance().pushWarningQueue("數據庫查詢Class目錄失敗");
AfxMessageBox(L"數據庫查詢Class目錄失敗");
str_class.clear();
return str_class;
}
if(p_Record->State)
p_Record->Close();
return str_class;
}
(五)析構函數釋放內存
CDataMange::~CDataMange(void)
{
if (p_Con->State)
p_Con->Close();
if(p_Con!=NULL)
p_Con.Release();
if(p_Com!=NULL)
p_Com.Release();
if (p_Record->State)
p_Record->Close();
if(p_Record!=NULL)
p_Record.Release();
}