本身实现智能指针

 智能指针是一种资源管理,经过对原始指针进行封装,在资源管理对象进行析构时对指针指向的内存进行释放;一般使用引用计数方式进行管理。html

一个基本实现以下:java

 1 class Counter{
 2 public:
 3     friend Class SmartPointer;
 4     Counter() {
 5         ptr = NULL;
 6         cnt = 0;
 7     }
 8 
 9     Counter(Object* p) {
10         ptr = p;
11         cnt = 1;
12     }
13 
14     ~Counter() {
15         delete ptr;
16     }
17 private:
18     Object* ptr;
19     int cnt;
20 };
21 
22 Class SmartPointer {
23 public:
24     SmartPointer(Object* p) {
25         ptr_counter    = new Counter(p);
26     }
27 
28     SmartPointer(const SmartPointer& sp) {
29         ptr_counter = sp.ptr_counter;
30         ptr_counter->cnt++;
31     }
32 
33     ~SmartPointer() {
34         ptr_counter->cnt--;
35         if (ptr_counter->cnt == 0) {
36             delete ptr_counter;
37         }
38     }
39 
40     SmartPointer& operator=(const SmartPointer& sp) {   //别忘了const 41         ptr_counter->cnt--;
42         if (ptr_counter->cnt == 0) {
43             delete ptr_counter;
44         }
45         ptr_counter = sp.ptr_counter;
46         ptr_counter->cnt++;
      return *this; // 赋值运算符重载都要返回*this
47 } 48 private: 49 Counter* ptr_counter; 50 };

 

Counter里的指针是Object*,由于是它也是指向这块内存的。算法

引用计数类Counter至关于对指针和cnt变量的一个包装。智能指针里把全部Object*类型的指针都转换成Counter*类型来处理。函数

 

follow up:this

1、如何获取智能指针所包装的指针对象spa

solution1:(naive).net

定义Object* GetPtr(), Object& GetObject(), 直接返回指针和指针的解引用。指针

solution2:(good)code

对指针的 ->(成员访问)和 *(解引用)进行运算符重载。【运算符重载原理见此文htm

即,在成员函数定义里加入这两个:

1 Object* operator->() {
2     return ptr_counter->ptr;
3 }
4 
5 Object& operator*() {
6     return *(ptr_counter->ptr);
7 }

 注意:成员访问符号->的重载是有递归性质的。

 

 2、引用计数带来的问题:循环引用

如何解决循环引用?

把循环引用的一方使用弱引用(weak_ptr),便可解除循环引用。   ref   ref2

 

3、auto_ptr, unique_ptr, shared_ptr的比较

http://blog.csdn.net/worldwindjp/article/details/18843087

 

4、java的垃圾回收机制  ref0    ref     

目前最基本的垃圾收集算法有四种:

1. 标记-清除算法(mark-sweep),

2. 标记-压缩算法(mark-compact),

3. 复制算法(copying)

4. 引用计数算法(reference counting)

 

具体原理:(示意图可参考ref0

1.标记-清除算法   ref

缺点:形成大量内存碎片

2.标记-压缩算法

该算法标记阶段和Mark-Sweep同样,可是在完成标记以后,它不是直接清理可回收对象,而是将存活对象都向一端移动,而后清理掉端边界之外的内存。

3.复制算法

它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另一块上面,而后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。

缺点:却对内存空间的使用作出了高昂的代价,由于可以使用的内存缩减到原来的一半。若是存活对象不少,那么Copying算法的效率将会大大下降。

4.引用计数算法

缺点:循环引用问题

 

Generational Collection(分代收集)算法

分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不一样的区域。通常状况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),老年代的特色是每次垃圾收集时只有少许对象须要被回收,而新生代的特色是每次垃圾回收时都有大量的对象须要被回收,那么就能够根据不一样代的特色采起最适合的收集算法。

目前大部分垃圾收集器对于新生代都采起Copying算法,由于新生代中每次垃圾回收都要回收大部分对象,也就是说须要复制的操做次数较少;

而因为老年代的特色是每次回收都只回收少许对象,通常使用的是Mark-Compact算法。

相关文章
相关标签/搜索