-
RefPtr,passRefPtr, adoptRefPtr, OwnPtr
RefPtr:引用计数
passRefPtr:用于函数参数和函数返回值。赋值给别人后,自己的内容置NULL.
AdoptRefptr():输入rawptr, 输出passRefPtr.
RefPtr<T>p = rawPtr; //引用计数为1
passRefPtr的函数:
PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }从raw指针构造passRefPtr.
PassRefPtr& operator=(T*); //raw直接赋值给passRefPtr,ref成为1。
PassRefPtr& operator=(const PassRefPtr&); //passRefPtr互相赋值,后者清空,ref不变。
refPtr的函数:
refPtr=〉passRefPtr:
PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; } //release()直接将refPtr转换为一个passRefPtr
refPtr互相赋值的话,前者所指对象的ref--,后者所指对象的ref++.
rawPtr=>passRefPtr://adoptRef把一个rawptr转换为一个passRefPtr.
template<typename T> inline PassRefPtr<T> adoptRef(T* p)
{
adopted(p);
return PassRefPtr<T>(p, true);
}
常用的使用场景:
(1)passRefPtr=>refPtr:把一个函数的passRefPtr类型的参数现赋值给一个refPtr.或者直接用refPtr的构造函数。
(2) refPtr=>passRefptr:很少有直接把refPtr赋值给passRefptr的,一般都是调用refptr.release()得到一个passrefptr.一般都是在函数内部通过refptr.release()得到一个passrefptr然后当作返回值返回出去。
(3)rawptr=>refptr:可以把一个rawPtr赋值给一个refptr.也可以通过refptr的构造函数从一个rawptr直接构造一个refptr
(4) refptr=>rawPtr:
步骤:refptr=>passRefptr=>rawPtr
rawPtr.release()转换成passPtr,然后调用passrefptr.leakRef得到rawPtr.这样就没有ref计数了。
template<typename T> inline T* PassRefPtr<T>::leakRef() const
{
T* ptr = m_ptr;
m_ptr = nullptr;
return ptr;
}
(5)rawPtr=>passRefPtr.赋值和构造函数
(6) passRefPtr=>rawPtr: 调用leakRef。
(7)注意,passRefPtr和RefPtr都有一个get()函数直接拿到rawPtr,但是不影响passRefPtr和refPtr本身的属性。
OwnPtr,adoptPtr(T*), passOwnPtr.
OwnPtr完全占有一个ptr,ownPtr析构应该会释放所拥有的对象.使用在一个函数内部,可以避免在函数内忘了释放该对象。如果不想释放可以调用release()函数得到一个passOwnPtr传递出去。
使用例子:
1 2 3 4 5 6 7 8 9 10 11 12 | PassOwnPtr
createInstance() { OwnPtr ret = adoptPtr(new MyClass); if (!checkA()) { return NULL; } if (!checkB()) { return NULL; } return ret.release(); } |
问题:可以把一个refPtr赋值给ownPtr么?据说不可以,据说一个ownPtr只可以从另一各ownPtr或者passOwnPtr赋值过来。
rawPtr=>ownPtr:使用passOwnPtr= adoptPtr(T*)
ownPtr=>rawPtr:可以用get()但是ownPtr依然有控制权,还可以用leakPtr,这样ownPtr就失去了控制权。
ownPtr=>passOwnPtr:调用release函数:passOwnPtr = ownPtr.release().,这样ownPtr就失去了控制权。PassOwnPtr可以作为函数返回值返回出去,在函数外部,可以赋值给一个ownPtr.
passOwnPtr=>ownPtr:直接赋值:ownPtr=passOwnPtr