多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > 《STL源碼剖析》---_auto_ptr.h閱讀筆記

《STL源碼剖析》---_auto_ptr.h閱讀筆記

來源:程序員人生   發布時間:2014-10-08 22:55:01 閱讀次數:1921次

auto_ptr是常用的智能指針,其實現很簡單,源代碼也很短,但是中間有個代理類auto_ptr_ref用的很巧妙,值得學習。

/* * Copyright (c) 1997-1999 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */ #ifndef _STLP_AUTO_PTR_H #define _STLP_AUTO_PTR_H _STLP_BEGIN_NAMESPACE // implementation primitive //auto_ptr基類,聲明指針和指針初始化操作 class __ptr_base { public: void* _M_p; void __set(const volatile void* p) { _M_p = __CONST_CAST(void*,p); } void __set(void* p) { _M_p = p; } }; //使用auto_ptr_ref,在源代碼后面舉例說明 template <class _Tp> class auto_ptr_ref { public: __ptr_base& _M_r; _Tp* const _M_p; //_M_r是引用,_M_p是常量指針,在構造函數初始化列表初始化 auto_ptr_ref(__ptr_base& __r, _Tp* __p) : _M_r(__r), _M_p(__p) { } //釋放,把基類_M_r指針設為空 _Tp* release() const { _M_r.__set(__STATIC_CAST(void*, 0)); return _M_p; } private: //explicitely defined as private to avoid warnings: //顯示定義,避免警告。 //重載“=”為私有函數,不允許調用 typedef auto_ptr_ref<_Tp> _Self; _Self& operator = (_Self const&); }; template<class _Tp> class auto_ptr : public __ptr_base { public: typedef _Tp element_type; typedef auto_ptr<_Tp> _Self; _Tp* release() _STLP_NOTHROW { _Tp* __px = this->get(); this->_M_p = 0; return __px; } void reset(_Tp* __px = 0) _STLP_NOTHROW { _Tp* __pt = this->get(); if (__px != __pt) delete __pt; this->__set(__px); } _Tp* get() const _STLP_NOTHROW #if !defined (__GNUC__) || (__GNUC__ > 2) //像C語言一樣,用static_cast<> { return __STATIC_CAST(_Tp*, _M_p); } #else //像C++一樣用reinterpret { return __REINTERPRET_CAST(_Tp*, _M_p); } #endif #if !defined (_STLP_NO_ARROW_OPERATOR) //返回指針 _Tp* operator->() const _STLP_NOTHROW { //斷言,確保返回指針不是空指針 _STLP_VERBOSE_ASSERT(get() != 0, _StlMsg_AUTO_PTR_NULL) return get(); } #endif //返回引用 _Tp& operator*() const _STLP_NOTHROW { //斷言,確保指針不是空指針,這樣才可以解引用 _STLP_VERBOSE_ASSERT(get() != 0, _StlMsg_AUTO_PTR_NULL) return *get(); } //顯示構造函數,不允許隱式調用 explicit auto_ptr(_Tp* __px = 0) _STLP_NOTHROW { this->__set(__px); } /* 復制構造函數,需要注意的是復制構造函數是auto_ptr傳遞的是指針的所有權。 因為要修改傳入參數的所有權,所以傳入參數不是const(不同于其他復制構造函數) auto_ptr<int>p1(new int(10)); auto_ptr<int>p2(p1); p2指向new int(10)后,p1就成了空指針,他們不能共享所有權,因此auto_ptr不能作為 容器元素,因為容器元素要支持拷貝和復制 */ #if defined (_STLP_MEMBER_TEMPLATES) # if !defined (_STLP_NO_TEMPLATE_CONVERSIONS) template<class _Tp1> auto_ptr(auto_ptr<_Tp1>& __r) _STLP_NOTHROW { _Tp* __conversionCheck = __r.release(); this->__set(__conversionCheck); } # endif template<class _Tp1> auto_ptr<_Tp>& operator=(auto_ptr<_Tp1>& __r) _STLP_NOTHROW { _Tp* __conversionCheck = __r.release(); reset(__conversionCheck); return *this; } #endif //同類型auto_ptr作為復制構造函數參數,不用模板 auto_ptr(_Self& __r) _STLP_NOTHROW { this->__set(__r.release()); } //賦值操作符和復制構造函數類型,傳遞的是所有權,不是值傳遞 _Self& operator=(_Self& __r) _STLP_NOTHROW { reset(__r.release()); return *this; } //析構函數很簡單,只是調用指針指向對象的析構函數,釋放指針指向的空間 //delete而不是delete[],所以auto_ptr不能指向數組 ~auto_ptr() _STLP_NOTHROW { /* boris : reset(0) might be better */ delete this->get(); } //使用auto_ptr_ref,在源代碼后面舉例說明 auto_ptr(auto_ptr_ref<_Tp> __r) _STLP_NOTHROW { this->__set(__r.release()); } _Self& operator=(auto_ptr_ref<_Tp> __r) _STLP_NOTHROW { reset(__r.release()); return *this; } #if defined(_STLP_MEMBER_TEMPLATES) && !defined(_STLP_NO_TEMPLATE_CONVERSIONS) template<class _Tp1> operator auto_ptr_ref<_Tp1>() _STLP_NOTHROW { return auto_ptr_ref<_Tp1>(*this, this->get()); } template<class _Tp1> operator auto_ptr<_Tp1>() _STLP_NOTHROW { return auto_ptr<_Tp1>(release()); } #else operator auto_ptr_ref<_Tp>() _STLP_NOTHROW { return auto_ptr_ref<_Tp>(*this, this->get()); } #endif }; _STLP_END_NAMESPACE #endif /* _STLP_AUTO_PTR_H */ // Local Variables: // mode:C++ // End:


auto_ptr是智能指針。在賦值(復制構造函數或賦值操作符)的時候是傳遞指針所用權,而不是傳遞值。所以在復制構造函數或復制操作符函數要取消原來指針的所有權,因此就不能把傳入的參數聲明為const類型。但是有些情況下,必須要聲明為const類型,例如

auto_ptr<int> p(auto_ptr<int>(new int(10));

使用臨時對象時,必須用const修飾

auto_ptr(auto_prt<int> const&),而auto_ptr要修改原來指針的所有權,聲明成了auto_ptr(auto_prt<int> &),上面代碼不能通過編譯。

再例如

auto_ptr<int> p1(NULL);

p1=(auto_ptr<int>(new int(10));

有和上面一樣的問題,臨時對象是右值,非const&不能指向右值。

這樣情況下就引入了auto_ptr_ref,auto_ptr可以隱式轉換為auto_ptr_ref,這樣上面的程序就不會出錯。


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 自拍偷拍图 | 尤物在线 | 校园春色 欧美 | 男女激情视频 | 伊人久久大香线蕉综合网站 | 中文字幕不卡高清免费 | 欧美性88xx | 日韩精品一区二区三区高清 | 最近中文字幕免费版在线3 最近中文字幕免费大全8高清 | 欧美国产日韩一区 | 亚洲乱码中文字幕 | 2018高清国产一道国产 | 日韩在线一区高清在线 | 18以下勿进色禁视频免费看 | 91精品欧美一区二区综合在线 | a级做爰毛片视频免费看 | 欧美日本在线播放 | 另类图片另类小说 | 亚洲欧美久久一区二区 | 自拍网址| 亚洲色图小说 | 欧美一区二区三区四区在线观看 | 最新在线中文字幕 | 久久精品女人毛片国产 | 欧美xxxxx性另类 | 校园春色亚洲激情 | 在线欧美69v免费观看视频 | 手机看片日韩日韩国产在线看 | 欧美特黄一级aa毛片 | 国产一区二区三区高清 | 啪网址| 久久受www免费人成看片 | 91欧美精品综合在线观看 | 亚洲成人毛片 | 欧美国产成人精品一区二区三区 | 亚洲国产激情一区二区三区 | 大香伊蕉在人线国产75视频 | 在线看黄网址 | a级特黄毛片免费观看 | 欧美成人鲁丝片在线观看 | 九色国产在线 |