1. 程式人生 > >sp wp-Android中定義了兩種智慧指標強指標sp和弱指標wp

sp wp-Android中定義了兩種智慧指標強指標sp和弱指標wp

中定義了兩種智慧指標型別,一種是強指標sp(strong pointer),另外一種是弱指標(weak pointer)。其實稱之為強引用和弱引用更合適一些。強指標與一般意義的智慧指標概念相同,通過引用計數來記錄有多少使用者在使用一個物件,如果所有使用者都放棄了對該物件的引用,則該物件將被自動銷燬。

弱指標也指向一個物件,但是弱指標僅僅記錄該物件的地址,不能通過弱指標來訪問該物件,也就是說不能通過弱智真來呼叫物件的成員函式或訪問物件的成員變數。要想訪問弱指標所指向的物件,需首先通過wp類所提供的promote()方法將弱指標升級為強指標。弱指標所指向的物件是有可能在其它地方被銷燬的,如果物件已經被銷燬,wp的promote()方法將返回空指標,這樣就能避免出現地址訪問錯的情況。

弱指標是怎麼做到這一點的呢?其實說白了一點也不復雜,原因就在於每一個可以被智慧指標引用的物件都同時被附加了另外一個weakref_impl型別的物件,這個物件中負責記錄物件的強指標引用計數和弱指標引用計數。這個物件是智慧指標的實現內部使用的,智慧指標的使用者看不到這個物件。弱指標操作的就是這個物件,只有當強引用計數和弱引用計數都為0時,這個物件才會被銷燬。

說了這麼多原理,下面該看看智慧指標該如何使用了。假設現在有一個類MyClass,如果要使用智慧指標來引用這個類的物件,那麼這個類需滿足下列兩個前提條件:

1:這個類是基類RefBase的子類或間接子類;

2:這個類必須定義虛建構函式,即它的建構函式需要這樣定義:

virtual ~MyClass();

滿足了上述條件的類就可以定義為Android智慧指標了,定義方法和普通指標類似。比如普通指標是這樣定義:

MyClass* p_obj;

智慧指標是這樣定義:

sp<MyClass> p_obj;

注意不要定義成sp<MyClass>* p_obj。這是初學者很容易犯的錯誤,這樣其實相當於定義了一個指標的指標。儘管在語法上沒有問題,但是最好不要這樣定義。

定義了一個智慧指標的變數,就可以象普通指標那樣使用它,包括賦值、訪問物件成員、作為函式的返回值、作為函式的引數等。比如:

p_obj = new MyClass(); // 注意不要寫成 p_obj = new sp<MyClass> 
sp<MyClass> p_obj2 = p_obj; 
p_obj->func(); 
p_obj = create_obj(); 
some_func(p_obj);

注意不要試圖delete一個智慧指標,即 delete p_obj。不要擔心物件的銷燬問題,智慧指標的最大作用就是自動銷燬不再使用的物件。不需要再使用一個物件後,直接將指標賦值為NULL即可:

p_obj = NULL;

上面說的都是強指標,弱指標的定義方法和強指標類似,但是不能通過弱指標來訪問物件的成員。下面是弱指標的示例:

wp<MyClass> wp_obj = new MyClass(); 
p_obj = wp_obj.promote(); // 升級為強指標。不過這裡要用.而不是->,真是有負其指標之名啊 
wp_obj = NULL; 

Android智慧指標用起來是很方便,在一般情況下最好使用智慧指標來代替普通指標。但是需要知道一個智慧指標其實是一個物件,而不是一個真正的指標,因此其執行效率是比不上普通指標的。所以在追求高效率執行的地方最好還是使用普通指標為好