C++中的智能指针
转载声明: 本文转自 http://www.cppblog.com/martin/archive/2009/03/03/martin_yahoo.html
==================================================================
C++中的智能指针应用分析
前段时间,在查控件的内存泄露时,最终找出一个错误:在使用XMLDom(COM)时,由于重复使用某接口指针前未释放Dispatch指针(Release),而导致内存泄露,而此类错误(如同BSTR类型的泄漏),VC的调试器和Bondcheck均无能为力。解决办法,似乎只有细心一途。
但只要稍稍仔细看看,就可发现,实际上如果正确使用VC提供的智能指针,是可以避免此问题的。
另外,一直为Java程序员津津乐道的内存使用无需管理的优势,一直知道用C++的智能指针可以模拟。但一直没实际动手做过,趁此分析之机,用C++简单包装了一个。反正粗看之下,可以达到与Java类似的效果,当然,C++的对象更高效且节省内存。
就以上所提到的,时间关系,我只能简单罗列几点,代码应该是正确的(但未检查)。前后文没什么逻辑关系,但如果要进一步应用C++的智能指针,相信会起到抛砖引玉之效。
一:关于纠错,MFC和ATL中智能指针的应用
1:在Windows中如何方便的查看当前进程使用的内存。
虽然代码简单,但对纠错时有大用处,不用不停的通过切换任务管理器来查看内存使用。代码如下:
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; } |
IXMLDOMDocument *pDoc = NULL; CoCreateInstance(...) …… pDoc->Release(); |
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!")); |
IXMLDOMDocumentPtr docPtr = NULL; docPtr.CreateInstance(...) …… |
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!")); |
Interface** operator&() throw() { _Release(); m_pInterface = NULL; return &m_pInterface; } |
3.3: nodePtr = nodePrt2 ,也不会有问题:
仔细查看源码,在=操作符中会调用Attach,而Attach的做法是:会先调用_Release();
3.4:再看看值传递:拷贝构造函数如下
template<> _com_ptr_t(const _com_ptr_t& cp) throw() : m_pInterface(cp.m_pInterface) { _AddRef(); } |
classA *pA = new classA; auto_ptr<classA> ptr1(pA); auto_ptr<classA> ptr2(pA); |
template<class T> class CountedPtr { T * ptr; long * counter; public: //构造 explicit CountedPtr(T* p = NULL) :ptr(p),count(new long(1){} //析构 ~CountedPtr() {Release();} //拷贝构造 CountedPtr(cont CountedPtr<T>& p) :ptr(p.ptr),count(p.count) {++*counter;} //=操作符 CountedPtr<T>& operator= (const CountedPtr<T>& p) { if(this!=&p) { Release(); ptr=p.ptr; counter=p.counter; ++*counter; } return *this; } //其它略 .... private: void Release() { if(--*counter == 0) { delete counter; delete ptr; } } } |
转载声明: 本文转自 http://www.bccn.net/Article/kfyy/vc/jszl/200608/4310_2.html (编程中国)
推荐参考: android智能指针(sp wp)