作者:朱金灿
来源:http://blog.csdn.net/clever101
先考考大家,下面一段程序,会有什么问题:
#include <iostream> #include <string> #include "boost/smart_ptr.hpp" class MyClass { public: MyClass() { m_count = 1; m_strName = _T("xiao ming"); } void Increase() { m_count++; std::wcout<<m_strName<<_T(" increase 1 ")<<std::endl; } void ChangeName() { m_strName = _T("xiao gang"); std::wcout<<_T("The new name is ")<<m_strName<<std::endl; } std::wstring GetName() { return m_strName; } ~MyClass() { std::wcout<<_T(" Destructor")<<std::endl; } private: int m_count; std::wstring m_strName; }; void Process(boost::shared_ptr<MyClass>& ptrParam) { ptrParam->Increase(); std::wcout<<ptrParam->GetName()<<_T(" enter Procees function")<<std::endl; } void CallFunction() { MyClass* pNewInstance = new MyClass(); { boost::shared_ptr<MyClass> ptrParam(pNewInstance); Process(ptrParam); } pNewInstance->ChangeName(); } int _tmain(int argc, _TCHAR* argv[]) { CallFunction(); system("pause"); return 0; }下午同事就遇到上面一段程序类似的问题,他不明白程序为何会在pNewInstance->ChangeName();这一句崩溃。当时我也不是很确定,就这样分析:智能指针变量boost::shared_ptr<MyClass>ptrParam作为一个局部变量,当离开其作用域时,估计是执行了MyClass析构函数。
晚上回来查了下资料,比较标准的解释是:智能指针自动地增加和减少它指向对象的引用计数,当对象引用计数减少到0的时候自动摧毁。如果一个函数使用智能指针作为参数,那么不要把一个没有被其他智能指针引用的对象常规指针作为参数传入到函数中。如果这样做,那么这个对象指针将会被摧毁掉。接下来是这个问题详细描述:
1 常规指针pkObject指向一个动态分配的对象,其引用计数为0。
2 传输pkObject到一个智能指针参数,编译器隐式调用智能指针的构造函数将pkObject转换到一个临时的智能指针,并将对象的引用计数增加到1。
3 在函数调用的作用域,这个临时智能指针通过调用智能指针的拷贝构造函数复制到一个局部智能指针中,并将对象的引用计数增加到2。
4 当函数调用返回的时候,局部智能指针被摧毁,并将对象的引用计数减少到1。
5 在调用完成的时候,临时智能指针对象也被摧毁,并将对象的引用计数减少到0,这导致对象被释放掉。
参考文献:
1.智能指针