• 智能指针变量做函数参数的一个值得注意的地方


    作者:朱金灿

    来源: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.智能指针

     

          如果你觉得我的博客对你有帮助,请在下面网址中博客之星评选活动投我一票:

    http://vote.blog.csdn.net/item/blogstar/clever101(单击候选人介绍下面的投他一票那个按钮)

    参与投票有机会获奖:

         最佳贡献奖:通过微博分享活动就有机会获得30元充值卡一张(每周抽选5名)
        幸运奖:凡参与投票用户就有机会获得精美小礼品一份。(每周抽选5名)
        积极参与奖:所有参与投票并符合条件的用户均可获得20个下载积分。



  • 相关阅读:
    用JS获取地址栏参数的方法(超级简单)
    js全选
    梦幻西游手游三界奇缘答题 文字解答
    父级div height:auto无效解决办法
    DropDownList赋值,绑定,传值
    《梦幻西游》手游人宠抗防修炼点修消耗表
    使客户端的控件ID保持不变,不受母版页的影响
    无法读取项目文件 .csproj
    七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
    MVC控件解析
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470827.html
Copyright © 2020-2023  润新知