• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            LoveBeyond

            STL auto_ptr智能指針簡單分析

            程序人生 >> STL auto_ptr智能指針簡單分析:a
            uto_ptr是STL里面的智能指針(Smart Pointer)
            ,一個(gè)很好的優(yōu)點(diǎn)就是指針?biāo)袡?quán)自動(dòng)轉(zhuǎn)移和指針自動(dòng)刪除技術(shù)。對(duì)于異常和經(jīng)常忘記delete的情況來說很實(shí)用。
            下面就是從SGI官方網(wǎng)站轉(zhuǎn)載的STL auto_ptr實(shí)現(xiàn)源碼(加上了我的注釋):
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            62
            63
            64
            65
            66
            67
            68
            69
            70
            71
            72
            73
            74
            75
            76
            77
            78
            79
            80
            81
            82
            83
            84
            85
            86
            87
            88
            89
            90
            91
            92
            93
            94
            95
            96
            97
            98
            99
            100
            101
            102
            103
            104
            105
            106
            107
            108
            109
            110
            111
            112
            113
            114
            115
            116
            117
            118
            119
            120
            121
            122
            123
            124
            125
            126
            127
            128
            129
            130
            131
            132
            133
            134
            135
            136
            137
            138
            139
            140
            141
            142
            143
            144
            145
            146
            147
            148
            149
            150
            151
            152
            
            /*
            * Copyright (c) 1997-1999
            * Silicon Graphics Computer Systems, Inc.
            *
            * Permission to use, copy, modify, distribute and sell this software
            * and its documentation for any purpose is hereby granted without fee,
            * provided that the above copyright notice appear in all copies and
            * that both that copyright notice and this permission notice appear
            * in supporting documentation.  Silicon Graphics makes no
            * representations about the suitability of this software for any
            * purpose.  It is provided "as is" without express or implied warranty.
            *
            */
             
            #ifndef __SGI_STL_MEMORY
            #define __SGI_STL_MEMORY
             
            #include <stl_algobase.h>
            #include <stl_alloc.h>
            #include <stl_construct.h>
            #include <stl_tempbuf.h>
            #include <stl_uninitialized.h>
            #include <stl_raw_storage_iter.h>
             
             
            __STL_BEGIN_NAMESPACE
            // 如果定義了auto_ptr轉(zhuǎn)換以及支持成員函數(shù)模板
            #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
            	defined(__STL_MEMBER_TEMPLATES)
            // 定義auto_ptr_ref template結(jié)構(gòu)體①
            template<class _Tp1> struct auto_ptr_ref {
            	_Tp1* _M_ptr;
            	auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {}
            };
             
            #endif
             
            template <class _Tp>
            class auto_ptr {
            private:
            	_Tp* _M_ptr;
             
            public:
            	typedef _Tp element_type;
            	// explicit修飾構(gòu)造函數(shù),防止從原始指針隱式轉(zhuǎn)換
            	explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
            	// Copy構(gòu)造函數(shù),注意這里是直接引用傳參(非const),同時(shí)轉(zhuǎn)移指針?biāo)袡?quán)
            	auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
             
            // 如果允許定義成員函數(shù)模板(Member Function Templates)②
            #ifdef __STL_MEMBER_TEMPLATES
            	// 如果可以從_Tp1*轉(zhuǎn)換為_Tp*,則可以從auto_ptr<_Tp1>構(gòu)造auto_ptr<_Tp>
            	// 同時(shí)轉(zhuǎn)移指針?biāo)袡?quán)
            	template <class _Tp1>
            	auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW
            		: _M_ptr(__a.release()) {}
            #endif /* __STL_MEMBER_TEMPLATES */
             
            	// 賦值操作符,同樣是非const引用傳參,有證同測試③
            	auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW {
            		// 如果是自我賦值,就直接返回
            		if (&__a != this) {
            			delete _M_ptr;
            			_M_ptr = __a.release();
            		}
            		return *this;
            	}
             
            #ifdef __STL_MEMBER_TEMPLATES
            	// 賦值操作符的Member Function Templates
            	template <class _Tp1>
            	auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW {
            		if (__a.get() != this->get()) {
            			delete _M_ptr;
            			_M_ptr = __a.release();
            		}
            		return *this;
            	}
            #endif /* __STL_MEMBER_TEMPLATES */
             
            	// Note: The C++ standard says there is supposed to be an empty throw
            	// specification here, but omitting it is standard conforming.  Its 
            	// presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2)
            	// this is prohibited.
            	// auto_ptr的析構(gòu)函數(shù)
            	~auto_ptr() { delete _M_ptr; }
            	// operator*定義,返回值
            	_Tp& operator*() const __STL_NOTHROW {
            		return *_M_ptr;
            	}
            	// operator->定義,返回指針
            	_Tp* operator->() const __STL_NOTHROW {
            		return _M_ptr;
            	}
            	// const成員函數(shù)get定義,返回指針
            	_Tp* get() const __STL_NOTHROW {
            		return _M_ptr;
            	}
            	// release函數(shù)定義,釋放指針
            	_Tp* release() __STL_NOTHROW {
            		_Tp* __tmp = _M_ptr;
            		_M_ptr = 0;
            		return __tmp;
            	}
            	// reset函數(shù)定義,重置指針
            	void reset(_Tp* __p = 0) __STL_NOTHROW {
            		if (__p != _M_ptr) {
            			delete _M_ptr;
            			_M_ptr = __p;
            		}
            	}
             
            	// According to the C++ standard, these conversions are required.  Most
            	// present-day compilers, however, do not enforce that requirement---and, 
            	// in fact, most present-day compilers do not support the language 
            	// features that these conversions rely on.
             
            #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
            	defined(__STL_MEMBER_TEMPLATES)
             
            public:
            	// 從auto_ptr_ref<_Tp>構(gòu)造auto_ptr<_Tp>
            	auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
            		: _M_ptr(__ref._M_ptr) {}
            	// 從auto_ptr_ref<_Tp>對(duì)auto_ptr<_Tp>進(jìn)行賦值操作。
            	// 注意這里是普通傳參,沒有引用④
            	auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW {
            		if (__ref._M_ptr != this->get()) {
            			delete _M_ptr;
            			_M_ptr = __ref._M_ptr;
            		}
            		return *this;
            	}
            	// 成員函數(shù)模板(Member Function Templates)②
            	// 如果可以從_Tp*轉(zhuǎn)換為_Tp1*,則可以從auto_ptr<_Tp>轉(zhuǎn)換為auto_ptr_ref<_Tp1>
            	template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW 
            	{ return auto_ptr_ref<_Tp1>(this->release()); }
            	// 成員函數(shù)模板(Member Function Templates)②
            	// 如果可以從_Tp*轉(zhuǎn)換為_Tp1*,則可以從auto_ptr<_Tp>轉(zhuǎn)換為auto_ptr<_Tp1>
            	template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW
            	{ return auto_ptr<_Tp1>(this->release()); }
             
            #endif /* auto ptr conversions && member templates */
            };
             
            __STL_END_NAMESPACE
             
            #endif /* __SGI_STL_MEMORY */
             
            // Local Variables:
            // mode:C++
            // End:

            注解:
            ①auto_ptr_ref結(jié)構(gòu)體
            我們看到,auto_ptr源代碼中的Copy構(gòu)造函數(shù)的參數(shù)是普通的引用傳參(不是const引用,也不是普通的傳值),這是為了方便指針擁有權(quán)的轉(zhuǎn)移(如果是const引用,那么擁有權(quán)無法轉(zhuǎn)移;如果是普通的傳值,oh my god,整個(gè)世界都徹底混亂了)。那如果以一個(gè)臨時(shí)對(duì)象(也就是所謂的右值)進(jìn)行拷貝構(gòu)造,那樣就無法通過編譯了(普通指針或引用不能指向const對(duì)象,即不能指向右值)。幸好有auto_ptr_ref的存在,可以從auto_ptr_ref臨時(shí)對(duì)象構(gòu)造或者賦值為auto_ptr對(duì)象:

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            
            public:
            	// 從auto_ptr_ref<_Tp>構(gòu)造auto_ptr<_Tp>
            	auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
            		: _M_ptr(__ref._M_ptr) {}
            	// 從auto_ptr_ref<_Tp>對(duì)auto_ptr<_Tp>進(jìn)行賦值操作。
            	// 注意這里是普通傳參,沒有引用④
            	auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW {
            		if (__ref._M_ptr != this->get()) {
            			delete _M_ptr;
            			_M_ptr = __ref._M_ptr;
            		}
            		return *this;
            	}

            而auto_ptr對(duì)象也可以隱式的轉(zhuǎn)化為auto_ptr_ref類型的對(duì)象:

            1
            2
            
            	template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW 
            	{ return auto_ptr_ref<_Tp1>(this->release()); }

            于是乎,就完美的完成了auto_ptr從右值到左值的轉(zhuǎn)換工作。也可以看這里:為什么需要auto_ptr_ref
            成員函數(shù)模板(Member Function Templates)
            ③證同測試,見《Effective C++》條款11:在operator= 中處理“自我賦值” (Item 11. handle assignment to self in operator=)
            ④見①

            原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明:
            本文出自程序人生 >> STL auto_ptr智能指針簡單分析
            作者:代碼瘋子

            posted on 2011-10-09 10:53 LoveBeyond 閱讀(2670) 評(píng)論(4)  編輯 收藏 引用

            <2011年10月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            導(dǎo)航

            統(tǒng)計(jì)

            留言簿(1)

            文章分類

            搜索

            積分與排名

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            友情鏈接:C++博客 LoveBeyond 代碼瘋子 程序人生 C++技術(shù)博客
            97r久久精品国产99国产精| 久久99亚洲网美利坚合众国| AA级片免费看视频久久| 91麻豆精品国产91久久久久久| 久久精品国产清自在天天线| 欧美日韩久久中文字幕| 无码人妻久久久一区二区三区| 久久91精品国产91久久麻豆| 国产精品丝袜久久久久久不卡| 亚洲人成网站999久久久综合| 久久人人爽人人爽人人片av高请 | 久久精品一区二区三区AV| 久久亚洲精品国产精品| 久久99精品久久久久久9蜜桃| 日产精品久久久久久久性色| 青青草原1769久久免费播放| 久久精品国产亚洲AV影院| 精品熟女少妇aⅴ免费久久| 久久午夜羞羞影院免费观看| 蜜臀久久99精品久久久久久 | 久久久精品波多野结衣| 无码人妻久久一区二区三区免费丨 | 亚洲第一永久AV网站久久精品男人的天堂AV| 人妻精品久久无码区| 综合久久精品色| 日韩欧美亚洲国产精品字幕久久久| 久久99免费视频| 精品熟女少妇a∨免费久久| 亚洲天堂久久久| 欧美午夜A∨大片久久| 午夜不卡888久久| 好久久免费视频高清| 久久国产热精品波多野结衣AV | 久久精品无码一区二区WWW| 久久久久国产亚洲AV麻豆| 日本免费一区二区久久人人澡 | 热99re久久国超精品首页| 国产亚洲综合久久系列| 看久久久久久a级毛片| 色偷偷88888欧美精品久久久| 香蕉久久夜色精品国产2020|