auto_ptr自己实现|临时对象是可度的吗


自己实现auto_ptr,与std::auto_ptr一样。

头文件 _auto_ptr.h

#ifndef __auto_ptr_H_
#define __auto_ptr_H_

//#define __debug
// _auto_ptr.h
// 自己实现一个auto_ptr
#include <iostream>
using namespace std;

template <typename T>
class _auto_ptr;


    
template <typename Y>
class tmp_class
{
public:
    explicit tmp_class(Y *tp_):tp(tp_){}

    Y *tp;
};

template <typename T>
class _auto_ptr
{
public:
    _auto_ptr():p(0)
    {
        #ifdef __debug
        cout<<"_auto_ptr():empty construction of _auto_ptr"<<endl;
        #endif
    }
    
    template <typename U>
    explicit _auto_ptr(U *pu):p( pu )  // 此处若写为 p(pu),则只接受原始指针的兼容赋值(一般是子类指针赋值给基类),
                                       // 若写为p((T*)pu),则进行了强制转换,使得float指针可以赋值给int指针
                                       // explicit抑制隐式转换
    {

        if(pu)
        {
           
            #ifdef __debug
            cout<<"_auto_ptr(U *pu): construction of _auto_ptr, obj="<<p<<"  "<<endl;
            #endif
        }else
        {
            #ifdef __debug
            cout<<"_auto_ptr(U *pu): construction of _auto_ptr, null=null"<<endl;
            #endif
        }
    }
    
    
    _auto_ptr( _auto_ptr<T>& cp):p( 0 )
    {
        p=cp._release();
        #ifdef __debug
        cout<<"_auto_ptr(const _auto_ptr<T>& cp):copy construction of _auto_ptr.obj="<<p<<"  "<<endl;
        #endif
    }
    
        //template<class U>
    operator tmp_class<T> ()
    {
        #ifdef __debug
        cout<<"_auto_ptr: hidden convert"<<endl;
        #endif
        return tmp_class<T>(this->_release());
        //return tmp_class<T>(this->p); // 用这句话代替上面一行代码,会发生什么?
                                        // 由于auto_ptr的独占性,本对象(A)将指针(控制权)转交给别人(B)以后,A的指针必须
                                        // 赋值为NULL,否则当A析构时,会将内存释放,而B还在继续使用该内存单元.
                                        // 这一点对  new T 产生的临时对象同样适用,因为该临时对象是可写的。(very important)
    }
    
//    template<class U>   // 如果加上这句,就成为成员函数模板,本函数内的<T>全部换为<U>即可
    _auto_ptr( tmp_class<T> cp):p( cp.tp )
    {
        #ifdef __debug
        cout<<"_auto_ptr: tmp_class<T> construction"<<endl;
        #endif
    }  // tmp_class<T> cp不能为引用
    




    _auto_ptr<T>& operator=(_auto_ptr <T>&cp)
    {
        if(&cp==this)
            return *this;
        _clear();
        p=cp._release();
        #ifdef __debug
        cout<<"_auto_ptr::operator=:operator"<<"obj="<<p<<"  "<<endl;
        #endif
        
        return *this;
    }

    ~_auto_ptr()
    {
        #ifdef __debug 
        cout<<"~_auto_ptr()"<<endl;
        #endif
        _clear();
    }
    
    
    T *operator->() {return &(operator*());}
    T &operator*() {return *p;}
    
    T* get()
    {
        return p;
    }
    
private:
    void _clear()
    {
        delete p;
        p=0;
    } 
    
    T *_release()
    {
       T *tmp=p;
       p=0;
       return tmp;
    }
    
private:
    T  *p;
};

#endif

main.cpp

#include <iostream>  

#include <memory> 

#define __debug


#include "_auto_ptr.h"


using namespace std;  



class T

{

public: 
    T(int v):y(v){cout<<"T 构造"<<endl;}

    ~T(){cout<<"T 析构"<<endl;}

    int y;
    friend ostream &operator<<(ostream &os, const T &t);

};


ostream &operator<<(ostream &os, const T &t)
{
    cout<<t.y;
    return os;    
}



int main()  

{  
    _auto_ptr<T>p3= _auto_ptr<T>(new T(4) );
    cout<<(*p3).y<<endl;

    return 0;  

  

}  


结果:

chen@chen-book1:~$ g++ -o cpp c.cpp -g
chen@chen-book1:~$ ./cpp
T 构造
_auto_ptr(U *pu): construction of _auto_ptr, obj=0x9605008  
_auto_ptr: hidden convert
_auto_ptr: tmp_class<T> construction
~_auto_ptr()
4
~_auto_ptr()
T 析构
chen@chen-book1:~$ 

_auto_ptr需要注意的是:

  不能共享,一个萝卜一个坑!

所以:

【1】因为不能共享,所以拷贝构造/赋值之后,原有的指针就失去了控制权。

【2】拷贝构造和operator=的参数是引用而不是常引用。这带来一个问题,就是临时对象怎么办?就像代码中

 _auto_ptr<T>p3= _auto_ptr<T>(new T(4) );
这使用了另外一个类来中转。它接受临时对象的指针来构造自己,再作为参数对auto_ptr进行构造。这需要一个tmp_class类型参数的构造函数,并将临时对象隐式转换为tmp_class。同时临时对象将自己的指针设置为null,从而交出了控制权。注意new出来的临时对象并非只读,而是可以改变的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值