发现大家对写库很热衷。不过,写一个库,用C++最麻烦的事情,就是你new完了要记着delete。不过,这么傻瓜化的操作,有没有办法让电脑自动完成呢?当然是可以的。思路有以下三点:
! n- P% \! L( I# t9 f, a 1、Parent对象。 : q0 n6 I5 p* z1 w, c
每一个对象,都要有唯一的parent,当parent析构时,要带动他所有的children析构。 0 |' F3 R6 R/ h
好处: 8 o. ~2 Z+ M7 o5 e8 r% C
实现简单,且具有逻辑性。
* n6 ?' R7 R9 j' v9 ]; L# l 比如:一个窗口,他的按键,就应该是这个窗口的children,当窗口析构的时候,按键也必须析构。 ) E3 y( _" a5 z" u( s3 |
坏处: 7 ?" f, R. F" ^" D" N
不可以有复制构造函数……
* b3 p- ]2 X) k1 x, s% a 这个也很好理解。A-->B-->C中,a是b的parent,b是c的parent,如果允许复制,B复制了个D,那C就有两个parent,究竟怎么析构呢? / }( @) c4 s) y, g; K6 c/ K9 r
开源库的实现: + V3 B& Z6 y" q; }" y- D8 x
Qt实现了这种方式的内存管理,尤其是对GUI框架,十分适用。 ! g& _5 O" f2 @
2、引用计数的SharedPtr
8 D/ l+ ] |' j0 o+ l' m9 M$ \ 指针,进行复制操作的时候,引用计数+1,析构的时候引用计数-1,当引用计数为0的时候,释放空间。 ) O- I1 ]7 u. y, Z1 l& X: ]
好处:
6 [0 `6 v4 s! _% l 实现简单
5 M% `8 D9 ?; W+ \6 t1 C% q 坏处: 0 k& F$ p9 J+ }( {+ i- G
具有循环引用的情况。要引入WeakPtr ; }0 `& j7 W; O. e, ?
开源库的实现:
2 \6 ], _" x! [; z6 Y Qt同时实现了这种技术,Boost也有相关实现。
7 z& i" V+ D2 K t* T$ E 我因为最近想自己实现一套Signalandslot库,也实现了SharedPtr,开源。 ; W1 x/ f! ^, Y
地址:http://gitorious.org/raylib/raylib/blobs/master/SmartPtr.hpp 3 U1 T$ U/ u3 `0 w
评述:
G# _5 m0 H! u4 K% o$ l! W 这是C++中最通用的实现手段,如果你要做一套类库,尝试使用SharedPtr,会让事情变得更加简单。
' W" }+ F8 u3 u4 Z# m: Y& ~" p1 e 3、重载new,实现GC 4 ^* V( m( f2 G0 c2 {- i6 {
直接重载C++操作符,实现垃圾回收。初始化一个内存池,当内存池满的时候,进行垃圾回收操作。 ' _! Y* d k1 [) m0 u A& D) B" k, H
好处:
0 v: F5 s7 [5 U: t. a 一劳永逸 + X4 d) h. A4 o
坏处:
3 w' s& @ [. M7 Q4 l \' d6 D 实现困难。 ) t. H1 R$ m9 X# O: }
占用内存大。
% C2 C3 f! J/ p1 o q* K) s 对已有的环境,不一定会有很好的支持。 + Z+ F8 `, j% H: D3 j
开源库的实现:
+ b. G* s' Q4 [! X" D1 L$ V python和java都有垃圾回收的实现,可以进行参考。
: w R) b, Y1 K0 G( p0 v 评述: 内存池也许不一定要做垃圾回收,如果是静态的内存池,可以加速内存分配的过程。 |