智能指示通常是通过引用计数器来自动维护对象的引用情况。引用计数跟踪该类有多少个对象共享同一指针。每次通过adoptRef函数创建智能指针时将引用计数置为1;当对象被另一个智能指针引用时增加与之相应的引用计数;对智能指针进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,析构函数减少引用计数(如果引用计数减至0,则删除基础对象)。
参考源码
RefPtr.h
Raw pointers
原始指针,即普通指针,相对智能指针而言。
RefPtr
WebKit中带有引用计数器的智能指针。
PassRefPtr
Raw pointers——>PassRefPtr
PassRefPtr<Node> prpPoint = adoptRef(new Node);
PassRefPtr——>RefPtr
PassRefPtr<Node> prpPoint = adoptRef(new Node);
RefPtr<Ring> Point= prpPoint ;
RefPtr——>PassRefPtr
PassRefPtr<Node> prpPoint = Point.release();
RefPtr——>Raw pointers
1) 从RefPtr或者PassRefPtr中获取原始指针Point.get()或者prpPoint.get()
如果指针的生命周期是确定的,本地变量可以使用原始指针。
如果本地变量需要维持对该对象的引用并确定它的生命周期,本地变量需要使用RefPtr
本地变量不应该使用PassRefPtr。
成员变量
如果指针的生命周期是确定的,成员变量可以使用原始指针。
如果该类需要维持对该对象的引用并确定它的生命周期,成员变量应该使用RefPtr
成员变量不应该使用PassRefPtr。
函数参数
如果函数不需要维持对该对象的引用,函数参数可以是原始指针。
如何函数需要维持对该对象的引用,函数参数应该是PassRefPtr。这种情况常见于大部分setter函数中。除非函数很简单,一般在该函数开始处应该将PassRefPtr转换成RefPtr。
函数返回值
如果函数的返回结果是一个对象,但是对象的所有关系没有被转移,返回结果应该是一个原始指针。这种情况常见于大部分getter函数中。
如果一个函数的返回结果是一个新对象或者对象的所有关系发生转移,返回的结果应该是一个PassRefPtr。
新对象
新对象应该在一创建的时候就立即转化为RefPtr指针,以便智能指针能够自动地对所有引用进行计数。
对象RefCounted类的对象,上面的过程需要用adoptRef方法转化。
好的使用智能指针的习惯应该是将类的构造函数定义为私有函数,并且定义一个共有的create函数用于创建类对象并且返回一个PassRefPtr指针。