1 /*
2 * Copyright (c) 1997-1999
3 * Silicon Graphics Computer Systems, Inc.
4 *
5 * Permission to use, copy, modify, distribute and sell this software
6 * and its documentation for any purpose is hereby granted without fee,
7 * provided that the above copyright notice appear in all copies and
8 * that both that copyright notice and this permission notice appear
9 * in supporting documentation. Silicon Graphics makes no
10 * representations about the suitability of this software for any
11 * purpose. It is provided "as is" without express or implied warranty.
12 *
13 */
14
15 #ifndef __SGI_STL_MEMORY
16 #define __SGI_STL_MEMORY
17
18 #include <stl_algobase.h>
19 #include <stl_alloc.h>
20 #include <stl_construct.h>
21 #include <stl_tempbuf.h>
22 #include <stl_uninitialized.h>
23 #include <stl_raw_storage_iter.h>
24
25
26 __STL_BEGIN_NAMESPACE
27
28 #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
29 defined(__STL_MEMBER_TEMPLATES)
30
31 template<class _Tp1> struct auto_ptr_ref {
32 _Tp1* _M_ptr;
33 auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {}
34 };
35
36 #endif
37
38 template <class _Tp> class auto_ptr {
39 private:
40 _Tp* _M_ptr; // 維護一個類型指針
41
42 public:
43 typedef _Tp element_type;
44
45 // 構造函數,初始化所維護的指針
46 explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
47
48 // 拷貝構造函數,轉移控制權,將__a維護的指針轉交給當前對象來維護;
49 auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
50
51 #ifdef __STL_MEMBER_TEMPLATES
52 template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW
53 : _M_ptr(__a.release()) {}
54 #endif /* __STL_MEMBER_TEMPLATES */
55
56 // 賦值構造函數,重新設定控制權
57 auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW {
58 if (&__a != this) {
59 delete _M_ptr; // 解除當前控制權,將所維護的指針所指向的對象析構掉。
60 _M_ptr = __a.release(); // 重新設定控制權,將__a維護的指針轉交給當前對象來維護。
61 }
62 return *this;
63 }
64
65 #ifdef __STL_MEMBER_TEMPLATES
66 template <class _Tp1>
67 auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW {
68 if (__a.get() != this->get()) {
69 delete _M_ptr;
70 _M_ptr = __a.release();
71 }
72 return *this;
73 }
74 #endif /* __STL_MEMBER_TEMPLATES */
75
76 // Note: The C++ standard says there is supposed to be an empty throw
77 // specification here, but omitting it is standard conforming. Its
78 // presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2)
79 // this is prohibited.
80 ~auto_ptr() { delete _M_ptr; } // 析構函數,釋放所維護指針指向的資源
81
82 _Tp& operator*() const __STL_NOTHROW {
83 return *_M_ptr; // 重載*操作符,返回對象引用
84 }
85 _Tp* operator->() const __STL_NOTHROW {
86 return _M_ptr; // 重載->操作符,返回對象地址
87 }
88 _Tp* get() const __STL_NOTHROW {
89 return _M_ptr; // 獲取所維護指針
90 }
91 _Tp* release() __STL_NOTHROW {
92 _Tp* __tmp = _M_ptr;
93 _M_ptr = 0; // 轉移控制權,當前對象不再維護任何指針
94 return __tmp; // 讓出控制權
95 }
96 // 重新設定控制權,如果以默認值調用,則釋放對象,結束控制權
97 void reset(_Tp* __p = 0) __STL_NOTHROW {
98 if (__p != _M_ptr) {
99 delete _M_ptr;
100 _M_ptr = __p;
101 }
102 }
103
104 // According to the C++ standard, these conversions are required. Most
105 // present-day compilers, however, do not enforce that requirement---and,
106 // in fact, most present-day compilers do not support the language
107 // features that these conversions rely on.
108
109 #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \
110 defined(__STL_MEMBER_TEMPLATES)
111
112 public:
113 auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
114 : _M_ptr(__ref._M_ptr) {}
115
116 auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW {
117 if (__ref._M_ptr != this->get()) {
118 delete _M_ptr;
119 _M_ptr = __ref._M_ptr;
120 }
121 return *this;
122 }
123
124 template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW
125 { return auto_ptr_ref<_Tp1>(this->release()); }
126 template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW
127 { return auto_ptr<_Tp1>(this->release()); }
128
129 #endif /* auto ptr conversions && member templates */
130 };
131
132 __STL_END_NAMESPACE
133
134 #endif /* __SGI_STL_MEMORY */
135
136
137 // Local Variables:
138 // mode:C++
139 // End: