• auto_ptr 要点解析


    今天看了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());
    	}
    };
  • 相关阅读:
    诺基亚为 Qt 增添 LGPL 授权选择
    Web Beans (JSR299): Q&amp;A with Specification Lead Gavin King
    Web Beans (JSR299): Q&amp;A with Specification Lead Gavin King
    诺基亚为 Qt 增添 LGPL 授权选择
    使用 Hibernate 进行大数据量的性能测试
    略谈如何在对话框创建视图类画图
    JBoss Seam 框架下的单元测试
    领域模型设计讨论与研究
    JBoss Seam 框架下的单元测试
    The use of FS/GS registers
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3310781.html
Copyright © 2020-2023  润新知