68 } 698 t+ G( O* S* ^( W) s
70 void set_ptr(int *ptr){
& Q3 _- F- H/ a8 e% ~% a 71 if (ptr != (this->ptr->p)){
% r7 ~# X H+ u% f z 72 this->ptr->p = ptr;
3 R& ^! C! I, r, \& o 73 }2 m' T& O x9 o6 c& Z$ k
74 }
% j# r$ `) ~% ~; F# D& T: l 75 int* get_ptr(){
+ _7 s( f/ X2 H( {+ G$ o 76 return ptr->p;
) E2 a; V9 [: g u X) [! g 77 }
( r% c2 t/ ^8 |9 n7 ^ 78};
, I5 ^6 ?7 c2 ~' S; i. P 791 c% W# i' h+ o. G
80void test(){( K4 O: Y/ ^% O+ \& N
81 int i = 0;; `/ G# j0 r$ t* O+ |, i
82 Has_Ptr hp(&i);
+ K F8 c6 J/ y# U 83 int j = 1;
5 O# ^" P& l# d1 y# a 84 Has_Ptr hp1(&j);" }$ R, }- L; p
85 hp1 = hp;
$ K9 g: _5 s* p0 S/ Q7 B# X' G 86}! O% A* c0 x1 _
87int _tmain(int argc, _TCHAR* argv[])
* J I+ ^# G- m 88{
6 B7 I# O$ h. U3 K% | s0 z 89 test();' k. e5 l' \( \4 a: Q8 r
90 return 0;
3 P/ C9 H( ^1 M' U' P* h 91}! T8 f- Y: q" X; A
当一个类的成员里面有指针的时候,使用默认拷贝构造函数的时候就会造成多个对象管理同一块内存
: Z3 I7 `, Y. B* Q 这样带来的后果就是,如果任意一个对象释放了这一块内存,那么其他的对象再来操作这块内存的时候就会发生预料不到的结果。4 N$ o" d4 g/ q1 }$ V+ y
为了避免对象中保存野指针从而引发的错误,提出了智能指针, 它能实现多个对象共享内存的自释放。
" T @+ i/ b; b5 u8 t4 q 其实这种实现有点类似于delphi中的接口,到处传来传去的,最后自释放,就是因为接口有引用计数,当引用计数为1的时候就把对象释放掉。0 H) |0 p1 v1 m8 v* c
C++中这种实现(C++ Primer书上借鉴来的),有几个比较巧妙的地方
1 M- m( b* D4 V9 m5 `1 p& G8 O ·Has_Ptr这个类其实是想保存一个int *的指针,为了避免悬垂指针的出现,我们使用了 I_Pointer这个类把悬垂指针包了一下,因此在Has_Ptr这个类的Public接口中不会出现I_Pointer,只会出现int *4 p3 \- I! M* T: ?7 t S* S0 r- ]
·事实上也不能出现I_Pointer, 因为Pointer的构造函数定义成Private,不允许在外面构造,只能在friend类中构造,I_Pointer是专门为Has_Ptr实现的8 j9 g: s- B$ O! D/ |3 D( F6 A
·要记住三元组(拷贝构造,赋值操作,析构),当其中一个需要有特殊操作的时候,其他的也需要有特殊操作,这个要形成定势思维。 |