设为首页 加入收藏

TOP

浅谈c++资源管理以及对[STL]智能指针auto_ptr源码分析,左值与右值(二)
2016-04-28 13:28:51 】 浏览:753
Tags:浅谈 资源管理 以及 STL 智能 指针 auto_ptr 源码 分析 左值与
--------------------------------------(2) auto_ptr(auto_ptr& rhs)throw():ap(rhs.release()) {} template auto_ptr(auto_ptr &rhs)throw():ap(rhs.release()) {} auto_ptr& operator=(auto_ptr&rhs)throw() { reset(rhs.release()); return *this; } template auto_ptr& operator=(auto_ptr &rhs)throw() { reset(rhs.release()); return *this; } //Dereference----------------------------------------------------(3) T& operator*()const throw() { return *ap; T* operator->()const throw() { return ap; } //Helper functions------------------------------------------------(4) //value access T* get()const throw() { return ap; } //release owner ship 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; } } //Special conversions-----------------------------------------------(5) template struct auto_ptr_ref { Y*yp; auto_ptr_ref(Y*rhs):yp(rhs){} }; auto_ptr(auto_ptr_ref rhs)throw():ap(rhs.yp) {} auto_ptr& operator=(auto_ptr_ref rhs)throw() { reset(rhs.yp); return*this; } template operator auto_ptr_ref ()throw() { return auto_ptr_ref (release()); } template operator auto_ptr ()throw() { return auto_ptr (release()); } };

在这之前,我要先说明源码中重复出现的throw()函数。throw()函数类似一个声明,保证了该函数不会抛出任何异常,因为STL需要保证异常安全

3.异常安全

异常安全是指,一个对象碰到异常之后,还能够保证自身的正确性。

C++中’异常安全函数”提供了三种安全等级:(取自推荐的文章: “C++中的异常安全性”)
1. 基本承诺:如果异常被抛出,对象内的任何成员仍然能保持有效状态,没有数据的破坏及资源泄漏。但对象的现实状态是不可估计的,即不一定是调用前的状态,但至少保证符合对象正常的要求。
2. 强烈保证:如果异常被抛出,对象的状态保持不变。即如果调用成功,则完全成功;如果调用失败,则对象依然是调用前的状态。
3. 不抛异常保证:函数承诺不会抛出任何异常。一般内置类型的所有操作都有不抛异常的保证。

其实不加这个throw()也是可以的,不过STL有时会要求加上。

4.智能指针auto_ptr源码分析

下面我将对auto_ptr的源码进行详细的分析:

首先是构造函数与析构函数:

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

    ~auto_ptr()throw() {
        delete ap;  // delete dynamic storage
    }

就如前面所讲,这个类的核心就在于含有一个模板指针aq,以及析构函数delete(释放)这个指针指向的动态内存。对于这个explicit,表明这个构造函数是一个显式的构造函数。除了满足谷歌风格以外,还限制了参数不能有隐式转换。

接着是复制构造函数和release():

//release owner ship
    T* release()throw()
    {
        T* tmp(ap); 
/*here is a type-transformation, it have definition in this class and I will analyse it in the following passage */
        ap = 0;  // set it to NULL after transfer the ownership
        return tmp;  // return the address of dynamic storage
    }
//Copy & assignment--------------------------------------------(2)
    auto_ptr(auto_ptr& rhs)throw():ap(rhs.release()) {}
    // call the release() to return the address of dynamic storage
    template
   
     auto_ptr(auto_ptr
    
     &rhs)throw():ap(rhs.release()) {} // also have the same function as above one auto_ptr& operator=(auto_ptr&rhs)throw() { reset(rhs.release()); // reset() will be analyse in the following passage return *this; } // overload "=", and reset() must pay attention to delete the dynamic storage of (*this) template
     
       auto_ptr& operator=(auto_ptr
      
       &rhs)throw() { reset(rhs.release()); return *this; } // also have the same function as the above one
      
     
    
   

正如前面所讲,复制构造函数是实现动态内存的ownership(所有权)的转移,而不是深拷贝。为什么不采用深拷贝?原因是:因为采用深拷贝就不再满足我们设计该智能指针的初衷

既然是实现ownership(所有权)的转移,那么要通过release()函数,让原所有权拥有者放出所有权,使之返回原类型的指针,即动态内存的地址, 将之作为新所有权拥有者复制构造函数的参数。然后自身置NULL,不过所有权的新拥有者也要注意赋值前内存的释放。

细心的人也许会感觉奇怪,auto_ptr是一个模板类,为什么在复制构造函数里既有尖括号,也有省略尖括号的。对于一个模板类,一般情况下不是都要加上尖括号么?

刚开始我也感觉奇怪,后来想明白了:
在auto_p

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇序列分割 题解&代码(C++) 下一篇数据结构与算法 - 图的邻接表表示..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目