18.5 reference counter

一.作用:共享类时,用于标记类被共享的次数。每被一个类共享, rc++ ;每有一个类结束共享, rc-- ;当 rc=0 时,被共享的类才被销毁。这避免了:

1.  某类已无共享,但仍留在内存中。

2.  某类仍被其他类共享,却被提前销毁。

模型, render state 均可被共享。

一般通过智能指针来管理 rc

Object 类的两个内容: 1 Run time type information;( 用于存储类的类型 )

                     2. reference counter. rc 变量及递增递减 rc 的函数)

内存泄露追踪系统: object 类中存在一个 static 成员 hash-map* InUse ,它用于追踪游戏系统存在的类,游戏初始化时,该 hash_map 为空,游戏进行时, hash_map 相应变化,游戏结束时, hash_map 应当为空,若不为空,则会由 static 函数 PrintInUse 输出,便于程序员处理内存泄露。

  二. 智能指针便是基于上述内存泄露追踪系统建立的:

1.  智能指针是模板类, template<class T> 该指针指向被共享的类 T ,智能指针的唯一 private 成员变量时指向被共享的类的一般指针。

2.  Sp constructor 会将 rc++ (每当为 T 声明一个 sp ,即是引用了一次), destructor 会将 rc-- (原理同上)

3.  赋值操作符的重载中,在调用 rc++ rc— 之前,会比较赋值双方是否相等,这是为了:

(1)       防止自我赋值。

(2)       防止意外的自我销毁。(先 ++ 1 ,后 0 ,检测到 0 立即自我销毁)

4.  Implict conversions 的作用有二:

(1)       使 sp 看起来似乎 支持了多态性(说明: node 基于 spatial ,因此 spatialptr* a=Nodeptr* b; 合法。然而, NodePtr 并非基于 SpatialPtr ,两者均为 Pointer 类的模板产物。)但是由于 implict conversions ,我们可以多态性。(代码见 p806

(2)       支持了 sp 是否为 null 的判断。(通过重载 bool 转换符实现)

  三,   智能指针在使用过程中应注意的问题。

1.  智能指针本身无需 new ,声明一个即可。注意: sp 完成使命后一定要赋值为 0 。(类似于一般指针。)

2.  Sp 只能指向动态分配内存的对象。

3.  将智能指针用作函数参数和返回值时应高度谨慎 !!!

问题的根源在于函数将参数传入时会执行一次 constructor ,(建立本地副本),函数结束时会进行一次 destructor 。什么没做,一次 con~ ,一次 des~ rc >1 >0, 会造成被共享类的销毁。

返回值同理。

解决办法是:使实参类型或接受返回值的变量类型也为 sp ,即避免类型转换。(因为在声明实参或接受返回值的变量时 rc 已经 +1 ,不会出现为 0 的情况。)

猜你喜欢

转载自blog.csdn.net/huazai434/article/details/5970398