【原创&交流】智能指针变量做函数参数的一个值得注意的地方解决办法

【原创&交流】智能指针变量做函数参数的一个值得注意的地方
先考考大家,下面一段程序,会有什么问题:

C/C++ code

#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. 智能指针






------解决方案--------------------
跟函数参数没关系吧,是 CallFunction中两个多余的大括号缩窄了shared_ptr的作用域
------解决方案--------------------
指针作为参数,我习惯传裸指针,少写点代码
------解决方案--------------------
智能指针变量做函数参数的一个值得注意的地方?任何对象都是同样的结果

同1L

大括号会改变对象的生命周期,不仅仅是美观
------解决方案--------------------
智能指针,学习下哈
------解决方案--------------------
既然使用了智能指针,就不应该在其他地方再使用原始指针,而且应该“分配资源即初始化”,避免有机会访问原始指针。忽略这些原则而去关注原始指针和智能指针的作用域,那是舍本取末啊