C++智能指針應(yīng)用分析

字號(hào):

一:關(guān)于糾錯(cuò),MFC和ATL中智能指針的應(yīng)用
    1:在Windows中如何方便的查看當(dāng)前進(jìn)程使用的內(nèi)存。
    雖然代碼簡(jiǎn)單,但對(duì)糾錯(cuò)時(shí)有大用處,不用不停的通過(guò)切換任務(wù)管理器來(lái)查看內(nèi)存使用。代碼如下:
    UINT C_BaseUtil::getProcessMemoryUsed()
    {
    UINT uiTotal = 0L;
    HANDLE hProcess = ::GetCurrentProcess();
    PROCESS_MEMORY_COUNTERS pmc;
    if(::GetProcessMemoryInfo(hProcess,&pmc,sizeof(pmc)))
    uiTotal = pmc.WorkingSetSize;
    return uiTotal;
    }
    注意:由于內(nèi)存使用會(huì)是一個(gè)不穩(wěn)定的過(guò)程,所以,需要在程序穩(wěn)定時(shí)進(jìn)行調(diào)用,才能準(zhǔn)確。
    2:在使用Com的Dispatch指針時(shí),如果不使用COM智能指針,容易出現(xiàn)的錯(cuò)誤。
    2.1:忘記在所有出口釋放指針。
    如:
    IXMLDOMDocument *pDoc = NULL;
    CoCreateInstance(...)
    ……
    pDoc->Release();
    錯(cuò)誤:如果中間代碼發(fā)生異常,則pDoc未能正常釋放,造成內(nèi)存泄露。
    2.2:重復(fù)使用同一指針變量,導(dǎo)致中間生成的Dispatch指針未能釋放。
    IXMLDOMNode *pNode = NULL;
    if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &pNode)) || pNode==NULL)
    throw(_T("selectSingleNode failed!"));
    if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &pNode)) || pNode==NULL)
    throw(_T("selectSingleNode failed!"));
    錯(cuò)誤:pNode未釋放就開(kāi)始第二次調(diào)用,造成內(nèi)存泄露。或者類似pNode = pNode2的這種寫(xiě)法,也隨手就出問(wèn)題了。必須調(diào)用if(pNode) {pNode->Release();pNode=NULL;}
    3:使用MFC提供的Com智能指針解決上述問(wèn)題。
    注意:可通過(guò)查看源碼,看到#import生成的智能指針的原型是_com_ptr_t。
    3.1:
    IXMLDOMDocumentPtr docPtr = NULL;
    docPtr.CreateInstance(...)
    ……
    這下不會(huì)有問(wèn)題了,因?yàn)閐ocPtr在析構(gòu)時(shí)會(huì)有正確的釋放處理。
    3.2:
    IXMLDOMNodePtr nodePtr = NULL;
    if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &nodePtr)) || nodePtr==NULL)
    throw(_T("selectSingleNode failed!"));
    if(FAILED(pDoc->selectSingleNode(_bstr_t("Workbook"), &nodePtr)) || nodePtr==NULL)
    throw(_T("selectSingleNode failed!"));
    不會(huì)出錯(cuò)了,因?yàn)開(kāi)com_ptr_t重載了&操作符,在取指針時(shí),有如下操作,嘿。
    Interface** operator&() throw()
    {
    _Release();
    m_pInterface = NULL;
    return &m_pInterface;
    }
    3.3: nodePtr = nodePrt2 ,也不會(huì)有問(wèn)題:
    仔細(xì)查看源碼,在=操作符中會(huì)調(diào)用Attach,而Attach的做法是:會(huì)先調(diào)用_Release();
    3.4:再看看值傳遞:拷貝構(gòu)造函數(shù)如下
    template<> _com_ptr_t(const _com_ptr_t& cp) throw()
    : m_pInterface(cp.m_pInterface)
    {
    _AddRef();
    }
    嗯,也不會(huì)有問(wèn)題。