Chinaunix首页 | 论坛 | 博客
  • 博客访问: 400405
  • 博文数量: 87
  • 博客积分: 2571
  • 博客等级: 少校
  • 技术积分: 920
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-29 13:10
文章分类

全部博文(87)

文章存档

2012年(49)

2011年(7)

2010年(26)

2009年(5)

分类: C/C++

2010-04-14 11:50:39

/*
   auto_ptr模板类
            唯一成员数据是一个模板类型指针
 
            作用:动态分配对象以及当对象不再需要时自动执行清理

                 int* p = new int(0);
                 auto_ptr ap(p);
                 从此不必关心应该何时释放p,也不用担心发生异常会有内存泄漏
            方式:
                  1.auto_ptr的做法是“所有权转移”,即拷贝或赋值的源对象将失去对“裸”指针的所有权,所以,与一般拷贝构造函数,赋值函数不同
                  2.拷贝或赋值的目标对象将先释放其原来所拥有的对象
            注意:
                 1.因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,两个auto_ptr不能同时拥有同一个对象
                 2.auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以不应该用auto_ptr来管理一个数组指针
                 3.构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型
*/

template class auto_ptr
{
    private:
        _Tp* _M_ptr;
   
    public:
        typedef _Tp element_type;

  
    //构造函数
    //explicit表示该构造函数禁止隐式类型转换,即传入的参数必须是_Tp*类型
    explicit auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) {}

    //同类型拷贝构造函数,参数是另一个auto_ptr,但该auto_ptr要释放自己包含的指针
    //这是一个move(因此:千万不要使用类型为auto_ptr的容器)
    auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) {}

    //不同类型的拷贝构造函数
    //也是move
    template
    auto_ptr(auto_ptr<_Tpl>& __a) throw() : _M_ptr(__a.release()) {}

    //同类型auto_ptr赋值操作符,__a释放自己包含的指针
    //本模板类用reset更新自己的指针为__a指针
    auto_ptr& operator=(auto_ptr& __a) throw()
    {
        reset(__a.release());
        return *this;
    }


    //不同类型的auto_ptr赋值操作符
    template
    auto_ptr& operator=(auto_ptr<_Tpl>& __a) throw()
    {
        reset(__a.release());
        return *this;
    }

    //析构函数
    //仅支持delete,不支持delete[]
    ~auto_ptr() { delete _M_ptr; }

    //重载dereference操作符
    element_type& operator* const throw()
    {
        _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
        return *_M_ptr;
    }

    //重载->操作符
    element_type* operator->() cosnt throw()
    {
        _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
        return _M_ptr;
    }

    //获取成员指针函数
    element_type* get() const throw() {  return _M_ptr; }
   
    //获取成员指针函数,同时将成员指针清零
    element_type* release() throw()
    {
         element_type* __tmp = _M_ptr;
         _M_ptr = 0;
         return _tmp;
    }

    //释放成员指针所指对象,同时给成员指针赋新值
    void reset(element_type* __p = 0) throw()
    {
         if(__p != _M_ptr)
         {
              delete _M_ptr;
              _M_ptr = __p;
         }
    }

    //从auto_ptr_ref构造auto_ptr的构造函数
    auto_ptr(auto_ptr_ref __ref) throw() : _M_ptr(__ref._M_ptr) {  }

    //从auto_ptr_ref的赋值操作符
    //因为这里要释放内存,所以要进行self-assignment检查
    auto_ptr& operator=(auto_ptr_ref __ref) throw()
    {
         if(__ref._M_ptr != this.get())
         {
              delete _M_ptr;
              _M_ptr = __ref._M_ptr;
         }
         return *this.
    }

    //本auto_ptr到其他任意类型auto_ptr_ref的conversation操作符重载
    template
    operator auto_ptr_ref<_Tp1>() throw()
    {
         return auto_ptr_ref<_Tp1>(this->release());
    }
   
};


//模拟auto_ptr的reference类型
//可被一个传回auto_ptr值的函数赋值
template struct auto_ptr_ref
{
    _Tp1* _M_ptr;
    explicit auto_ptr_ref(_Tpl* __p) : _M_ptr(__p) {  }
};

 

 

 

   

阅读(1037) | 评论(0) | 转发(0) |
0

上一篇:stl准备

下一篇:[apache]filter入门

给主人留下些什么吧!~~