mBase指向RefBase
mRefs指向weakref_impl
感覺上,智能指標用在new出來的對象。因為new是分配一快記憶體,返回的是一個指標,系統也不知道使用者不再用這個記憶體。所以只有使用者顯式的釋放記憶體,
這樣有可能造成記憶體。所以,要把這個指標加以管理。new出來的對象的缺點是生存周期太長,而且只能用顯式的delete。所以要,構造一個放在堆棧中的對象管理這個指標。
這個對象就是智能指標了。當智能指標的生命週期結束時,系統會自動調用智能指標的解構函式,在這個解構函式添加釋放要管理的指標。一舉兩得。很巧妙。
還有更巧妙的:
比如
sp<AMessage> meta = parseBuffer->meta();
meta->findInt64("timeUs", &timeUs)
meta明明是一個對象,怎麼能用“->”
是因為sp類把“->”操作符重載了。wp類沒有‘->’重載符,所以不能操作對象。
inline T* operator-> () const { return m_ptr; }
這下好了,meta可以像普通的指標那樣用了。
我還是有一個疑問,既然智能指標這麼好,怎麼c++原生不支援呢?
深入體會一下sp的魅力
顯存釋放相關代碼可參考
"frameworks/native/libs/gui/SurfaceTextureClient.cpp" 844 lines --79%--
void SurfaceTextureClient::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i].buffer = 0;
}
}
buffer是sp類型。
=0調用的重載符如下:
template<typename T>
sp<T>& sp<T>::operator = (T* other)
{
if (other) other->incStrong(this);
if (m_ptr) m_ptr->decStrong(this);
m_ptr = other;
return *this;
}
other要加強引用,因為又有一個指標指向對象。
m_ptr要減強應用,因為被賦值的sp,不再指向原來的對象,所以引用計數要減一。
太巧妙,把零的情況也考慮進去。
注意阿,重載符號“=”,有四個實現,別找錯了。
明白一點東西,很不容易阿。