COM的引用计数规则

来源:百度文库 编辑:神马文学网 时间:2024/04/28 14:54:47
“COM本质论”一书对COM的引用计数规则精简为以下3个公理:
(1)当一个非空的接口指针从一个内存位置被copy到另一个内存位置时,应该要调用AddRef,以便通知对象“又有附加的引用发生了”。
(2)对于已经包含非空接口指针的内存位置来说,在重写该内存位置之前,必须要先调用Release,以便通知对象“这个引用已经被销毁了”。
(3)如果你对两个或者多个内存位置之间的关系有特殊的理解的话,那么多余的Addref和Release调用可以被优化掉。这样做主要是为了将“可能会混淆的状态”映射到健全和敏感的代码片断(例如,临时的堆栈变量和编译器产生的代码中的变量并不需要被引用技术)。
根据这3个公理,我们得到了实际的编程指导原则,以便确定什么时候应该调用Addref和Release,什么时候不该调用。
下面是4条比较通用的要求调用Addref方法的情况:
A1 当把一个非空接口指针写到局部变量中时。
A2 当被调用方把一个非空接口指针写到方法或者函数的[out]或者[in,out]参数中时。
A3 当被调用方返回一个非空接口指针作为函数的实际结果时。
A4 当把一个非空接口指针写到对象的一个数据成员中时。
下面是4条比较通用的要求调用Release方法的情况:
R1 当改写一个非空局部变量或者数据成员之前。
R2 在离开非空局部变量的作用域之前。
R3 当被调用方要改写方法或者函数的in,out]参数,并且参数的初始值为非空时。注意:[out]参数往往被假定“输入时为空值”,所以被调用方永远也不必释放[out]参数。
R4 在改写一个对象的非空数据成员之前。
R5 在离开一个对象的析构函数之前,并且这时还有一个非空接口指针作为数据成员。
还有一种很常见的特殊情况是:
S1 当调用方把一个非空接口指针通过[in]参数传给一个函数或者方法时,既不需要调用Addref,也不需要调用Release,因为在调用堆栈中,临时变量的生命周期只是“用于初始化形式参数”的表达式的生命周期的一个子集。