今天看了auto_ptr类的用法,又仔细看了看C++标准库中的符合标准的auto_ptr类别的实作,觉得自己基本上理解了auto_ptr的原理,下面就我的心得写几句,有不正确的地方,希望多多指教。
1. 初始化auto_ptr(T* ptr = 0);参数必须是new申请的空间,而且不能是数组。
2. 看代码:
auto_ptr(auto_ptr& ths):ap(ths.release()){} template<class Y> auto_ptr(auto_ptr<Y>& rhs):ap(rhs.release()){} //继承用,父类指针指向基类 auto_ptr& operator =(auto_ptr& rhs) { reset(rhs.release()); return *this; } template<class Y> auto_ptr& operator=(auto_ptr<Y>& rhs) // 比如Y为double,T为int,可以实现这种隐式转换 { reset(rhs.release()); return *this; }
3. 特殊转换与禁用const 类型的大部分功能,比如:赋值和初始化
auto_ptr(auto_ptr& ths):ap(ths.release()){} //抑制产生Myauto_ptr(const Myauto_ptr& ths), //没有这个函数就不能对用const auot_ptr<int> p // auto_ptr<int> pp(p);是错误的 auto_ptr& operator =(auto_ptr& rhs) // 同样参数不用const修饰,auto_ptr<int> pp = p;也是错误的 //你发现const auto_ptr<int> p 通过限制,使其拥有权不会发生转移 // 但是允许auto_ptr<int> p = auto_ptr<int>(new int(1));就需要通过 auto_ptr_ref机制来实现 //auto_ptr<int>(new int(1)) 产生一个临时变量,这个临时变量需要赋给 参数为 const auto_ptr<int>& //类型的参数,因为没有这个默认的复制构造函数, //所以无法转换,但是通过下面的函数可以正确执行。 //1.auto_ptr<int>(new int(1)) 产生一个临时对象 //2.operator auto_ptr_ref<Y>() 隐式转换为 auto_ptr_ref对象 //3.auto_ptr(auto_ptr_ref<T> rhs) 构造出一个auto_ptr对象 //这就是引入这个auto_ptr_ref的原因,但是肯定不止这些用意,也许有其他的用意,以后再补上。 template<class Y> struct auto_ptr_ref auto_ptr(auto_ptr_ref<T> rhs) auto_ptr& operator=(auto_ptr_ref<T> rhs) template<class Y> operator auto_ptr_ref<Y>() template<class Y> operator auto_ptr<Y>()
4.程序的示例(为了在编译器好运行,我把auto_ptr 改为 Myauto_ptr,防止和标准库的重复)
template<class Y> struct Myauto_ptr_ref { Y* yp; Myauto_ptr_ref(Y* ths):yp(ths){} }; template<class T> class Myauto_ptr { private: T* ap; public: typedef T element_type; explicit Myauto_ptr(T *ptr = 0):ap(ptr){} Myauto_ptr(Myauto_ptr& ths):ap(ths.release()){} template<class Y> Myauto_ptr(Myauto_ptr<Y>& rhs):ap(rhs.release()){} //继承用,父类指针指向基类 Myauto_ptr& operator =(Myauto_ptr& rhs) { reset(rhs.release()); return *this; } template<class Y> Myauto_ptr& operator=(Myauto_ptr<Y>& rhs) { reset(rhs.release()); return *this; } ~Myauto_ptr() { delete ap; } T* get() { return ap; } T& operator*() const { return *ap; } T* operator->()const { return ap; } T* release() { T* tmp(ap); ap = 0; return tmp; } void reset(T* ptr = 0) { if(ap != ptr) { delete ap; ap = ptr; } } Myauto_ptr(Myauto_ptr_ref<T> rhs) : ap(rhs.yp){} Myauto_ptr& operator=(Myauto_ptr_ref<T> rhs) { reset(rhs.yp); return *this; } template<class Y> operator Myauto_ptr_ref<Y>() { return Myauto_ptr_ref<Y>(release()); } template<class Y> operator Myauto_ptr<Y>() { return Myauto_ptr<Y>(release()); } };