[WebKit]RefPtr和PassRefPtr基础[1]
历史:
???? 在WebKit中,许多对象采用了引用计数。这种模式是通过类的ref,deref成员函数来递增和递减对象的引用记数。调用一次ref必须调用一次deref。当对象的引用记数为0的时候,对象就被删除。WebKit中许多类创建的新对象引用记数都为0,看了源代码新对象引用计数为1,可能源码把改过了,去掉了这个概念 .? deref的时候,代码里面会进行判断当引用计数为1时,会删除这个对象,否则 --引用计数 . 所以使用时,在不共享的情况下,不需要手工调用ref函数, 只需不要时deref掉就可以了? 这被称作是浮动状态(Floating State)。在浮动状态的对象必须调用ref,在删除之前必须调用deref。WebCore中许多类通过继承RefCounted模版类来实现这种模式。
在2005年的时候,我们发现存在很多内存泄漏的问题,特别实在WebCore编辑器代码中,这主要是由没有正确的使用ref和deref调用,还有就是创建的对象没有调用ref,依然是浮动状态。
???? 我们决定我们使用智能指针来解决这个问题,然而,一些前期的实验表明,智能指针导致引用记数的其他操纵影响性能。例如,一个函数使用智能指针来传递参数,函数返回时也使用这个智能指针作为返回值,仅仅在一个对象从一个智能指针移动到另外一个时,传递参数和返回函数值时就递增和递减引用记数2-4次。因此,我们寻求一种能够让我们使用智能指针又避免使用这种引用记数的性能流失的方法。
这种解决方案的灵感来源于C++的标准模版类auto_ptr。应用这种模式的对象在赋值的时候将传递了所有权。当你把一个auto_ptr传递给另外一个时,传递者变为0。
????? Maciej Stachowiak设计了一对模版类,RefPtr和PassRefPtr,它为WebCore的引用记数实现了这种模式。
原始指针:
????? 在讨论如RefPtr模版类这类智能指针时,我们使用原始指针来构建,下面是使用原始指针写的规范的Setter函数。
RefPtr<Node> a = createSpecialNode(); Node* b = getOrdinaryNode(); // the * operator *a = value; // the -> operator a->clear(); // null check in an if statement if (a) log("not empty"); // the ! operator if (!a) log("empty"); // the == and != operators, mixing with raw pointers if (a == b) log("equal"); if (a != b) log("not equal"); // some type casts RefPtr<DerivedNode> d = static_pointer_cast<DerivedNode>(a);?