CONTENTS
测试类:
class TestCls { public: string name; int x; TestCls(string _name):name(_name) { cout<<"TestCls "<<name.c_str()<<" Constructor Called\n"; } ~TestCls() { cout<<"TestCls "<<name.c_str()<<" Destructor Called\n"; } };
最简单的使用方法:
void testAutoPtrFunc() { cout<<"enter testAutoPtrFunc\n"; //这里直接new一个实例,由于使用了auto_ptr,会自动delete。 std::auto_ptr<TestCls> auptr1(new TestCls("TEST")); cout<<"leave testAutoPtrFunc\n"; }
输出:
enter testAutoPtrFunc TestCls TEST Constructor Called leave testAutoPtrFunc TestCls TEST Destructor Called
赋值,复制等逻辑:
void testAutoPtrFunc() { cout<<"enter testAutoPtrFunc\n"; std::auto_ptr<TestCls> auptr1(new TestCls("TEST")); cout<<"auptr1.get():"<<auptr1.get()<<endl; //auto_ptr只能有一个有效引用,因此赋值和复制会自动释放当前的引用。 std::auto_ptr<TestCls> auptr2(auptr1); cout<<"auptr1.get():"<<auptr1.get()<<endl; cout<<"auptr2.get():"<<auptr2.get()<<endl; std::auto_ptr<TestCls> auptr3 = auptr2; cout<<"auptr2.get():"<<auptr2.get()<<endl; cout<<"auptr3.get():"<<auptr3.get()<<endl; cout<<"leave testAutoPtrFunc\n"; }
输出:
enter testAutoPtrFunc TestCls TEST Constructor Called auptr1.get():0044CBE8 auptr1.get():00000000 auptr2.get():0044CBE8 auptr2.get():00000000 auptr3.get():0044CBE8 leave testAutoPtrFunc TestCls TEST Destructor Called
常用方法:
void testAutoPtrFunc() { cout<<"enter testAutoPtrFunc\n"; TestCls *pTest = new TestCls("TEST"); pTest->x = 10; cout<<"x:"<<pTest->x<<endl; std::auto_ptr<TestCls> auptr1(pTest); pTest = NULL;//交给auto_ptr了,就不需要自己在管理了,可以防止误删除 cout<<"x:"<<auptr1->x<<endl;//可以直接调用参考类的共有方法或者变量。 cout<<"x:"<<auptr1.get()->x<<endl;//可以通过get方法获取原指针。 TestCls &testCls = *auptr1; testCls.x = 100;//可以通过*获取参考指针的引用。 cout<<"x:"<<testCls.x<<endl; //可以通过release方法重新拿回指针,这样就需要自己管理 pTest = auptr1.release(); delete pTest; pTest = NULL; TestCls *pTestA = new TestCls("A"); TestCls *pTestB = new TestCls("B"); std::auto_ptr<TestCls> auptr2(pTestA); //调用reset,会先释放掉原有引用(pTestA),然后再持有新的引用(pTestB) auptr2.reset(pTestB); cout<<"leave testAutoPtrFunc\n"; }
输出:
enter testAutoPtrFunc TestCls TEST Constructor Called x:10 x:10 x:10 x:100 TestCls TEST Destructor Called TestCls A Constructor Called TestCls B Constructor Called TestCls A Destructor Called leave testAutoPtrFunc TestCls B Destructor Called
参考网址【 http://www.cplusplus.com/reference/memory/auto_ptr/ 】
auto_ptr 和 auto_ptr_ref :
参考【 http://www.cnblogs.com/woud/archive/2013/05/15/3080644.html 】和【 http://jarfield.iteye.com/blog/746062 】,讲的非常透彻。
最后贴下源码:
template<class _Ty> struct auto_ptr_ref { // proxy reference for auto_ptr copying explicit auto_ptr_ref(_Ty *_Right) : _Ref(_Right) { // construct from generic pointer to auto_ptr ptr } _Ty *_Ref; // generic pointer to auto_ptr ptr }; template<class _Ty> class auto_ptr { // wrap an object pointer to ensure destruction public: typedef auto_ptr<_Ty> _Myt; typedef _Ty element_type; explicit auto_ptr(_Ty *_Ptr = 0) _THROW0() : _Myptr(_Ptr) { // construct from object pointer } auto_ptr(_Myt& _Right) _THROW0() : _Myptr(_Right.release()) { // construct by assuming pointer from _Right auto_ptr } auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0() { // construct by assuming pointer from _Right auto_ptr_ref _Ty *_Ptr = _Right._Ref; _Right._Ref = 0; // release old _Myptr = _Ptr; // reset this } template<class _Other> operator auto_ptr<_Other>() _THROW0() { // convert to compatible auto_ptr return (auto_ptr<_Other>(*this)); } template<class _Other> operator auto_ptr_ref<_Other>() _THROW0() { // convert to compatible auto_ptr_ref _Other *_Cvtptr = _Myptr; // test implicit conversion auto_ptr_ref<_Other> _Ans(_Cvtptr); _Myptr = 0; // pass ownership to auto_ptr_ref return (_Ans); } template<class _Other> _Myt& operator=(auto_ptr<_Other>& _Right) _THROW0() { // assign compatible _Right (assume pointer) reset(_Right.release()); return (*this); } template<class _Other> auto_ptr(auto_ptr<_Other>& _Right) _THROW0() : _Myptr(_Right.release()) { // construct by assuming pointer from _Right } _Myt& operator=(_Myt& _Right) _THROW0() { // assign compatible _Right (assume pointer) reset(_Right.release()); return (*this); } _Myt& operator=(auto_ptr_ref<_Ty> _Right) _THROW0() { // assign compatible _Right._Ref (assume pointer) _Ty *_Ptr = _Right._Ref; _Right._Ref = 0; // release old reset(_Ptr); // set new //将本地的释放掉,然后将右值赋予本地 return (*this); } //当auto_ptr离开了作用域之后,就会调用析构函数,这里会delete掉管理的指针,也是 //auto_pter的核心所在 ~auto_ptr() _NOEXCEPT { // destroy the object delete _Myptr; } //重载了*,返回的就是管理指针的引用 _Ty& operator*() const _THROW0() { // return designated value #if _ITERATOR_DEBUG_LEVEL == 2 if (_Myptr == 0) _DEBUG_ERROR("auto_ptr not dereferencable"); #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ return (*get()); } //重载了->,返回的就是管理的指针 _Ty *operator->() const _THROW0() { // return pointer to class object #if _ITERATOR_DEBUG_LEVEL == 2 if (_Myptr == 0) _DEBUG_ERROR("auto_ptr not dereferencable"); #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ return (get()); } //get直接返回管理的指针 _Ty *get() const _THROW0() { // return wrapped pointer return (_Myptr); } //release时会将管理的指针返回,然后将本地管理置NULL _Ty *release() _THROW0() { // return wrapped pointer and give up ownership _Ty *_Tmp = _Myptr; _Myptr = 0; return (_Tmp); } //reset时会先将已有的指针delete掉,然后再保存新的。这里新的可以为空,这样可以提前释放管理的指针 void reset(_Ty *_Ptr = 0) { // destroy designated object and store new pointer if (_Ptr != _Myptr) delete _Myptr; _Myptr = _Ptr; } private: //管理的指针 _Ty *_Myptr; // the wrapped object pointer };
发表评论