c++/cpp中auto_ptr用法分析

41 篇文章 1 订阅

本文将分析一下c++中自带的auto_ptr在使用中需要注意的一个问题。首先看一段代码:

// auto_ptr example
#include <iostream>
#include <memory>
using namespace std;
int main () 
 {
        auto_ptr<int> p1 (new int);
        *p1.get()=10;

        {
        	auto_ptr<int> p2 (p1);
        	cout << "p2 points to " << *p2 << "\n";
        }
        cout << "p1 points to " << *p1 << "\n";
        return 0;
}
猜测一下这段程序的输出?如果不出意外,得到的结果应该是如下这样的。

p2 points to 10
Segmentation fault (core dumped)

你可能会奇怪,为什么对p1的引用会出现段错误了呢?好吧,我们来看一下auto_ptr的源代码。

namespace std {
    // auxiliary type to enable copies and assignments (now global)
    template<class Y>
    struct auto_ptr_ref {
        Y* yp;
        auto_ptr_ref (Y* rhs)
         : yp(rhs) {
        }
    };

    template<class T>
    class auto_ptr
    {
    private:
        T* ap;    // refers to the actual owned object (if any)
    public:
        typedef T element_type;

        // constructor
        explicit auto_ptr (T* ptr = 0) throw() : ap(ptr) { }

        // copy constructors (with implicit conversion)
        // - note: nonconstant parameter
        auto_ptr (auto_ptr& rhs) throw() : ap(rhs.release()) { }

        template<class Y>
        auto_ptr (auto_ptr<Y>& rhs) throw() : ap(rhs.release()) { }

        // assignments (with implicit conversion)
        // - note: nonconstant parameter
        auto_ptr& operator= (auto_ptr& rhs) throw()
        {
            reset(rhs.release());
            return *this;
        }
        template<class Y>
        auto_ptr& operator= (auto_ptr<Y>& rhs) throw()
        {
            reset(rhs.release());
            return *this;
        }

        // destructor, 注意这里释放内存。。
        ~auto_ptr() throw()
        {
            delete ap;
        }

        // value access
        T* get() const throw()
        {
            return ap;
        }
        T& operator*() const throw()
        {
            return *ap;
        }
        T* operator->() const throw()
        {
            return ap;
        }

        // release ownership
        T* release() throw()
        {
            T* tmp(ap);
            ap = 0;
            return tmp;
        }

        // reset value
        void reset (T* ptr=0) throw()
        {
            if (ap != ptr)
            {
                delete ap;
                ap = ptr;
            }
        }
	}
}
一般我们会认为智能指针都是采用一种引用计数的方式来管理已分配的内存,也就是说会在最后一个智能指针对象调用析构函数时将分配的内存释放掉,然而仔细看auto_ptr的源代码会发现,其实它的实现并没有采用引用计数的方式来实现,因为只要任何一个auto_ptr对象调用析构函数,内存就一定会被释放掉,这就是为何对p1的引用会出现段错误,因为p2在对p1引用之前已经将分配的内存给释放掉了。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值