android::sp
是 Android 中的智能指針(Smart Pointer)的實現,用于管理對象的生命周期,避免手動管理內存泄漏等問題。它是 Android libutils
庫中重要的一部分,常用于管理繼承自 android::RefBase
的對象。
與標準庫中的 std::shared_ptr
類似,android::sp
是引用計數智能指針。它會在對象的引用計數變為零時自動釋放對象。此外,Android 還提供了 wp
(弱指針),用于解決循環引用的問題。
sp
的特性
- 引用計數管理:基于
android::RefBase
的引用計數,確保對象安全銷毀。 - 自動釋放資源:當沒有任何
sp
指針指向一個對象時,自動銷毀該對象。 - 線程安全:
sp
和wp
提供線程安全的引用計數操作。
使用場景
sp
通常用于管理繼承自 android::RefBase
的對象。在 Android 的 HAL(硬件抽象層)和 Binder 通信中非常廣泛。
實現原理
sp
的核心是對目標對象的引用計數進行管理。目標對象必須繼承 android::RefBase
,因為 RefBase
提供了引用計數的功能。
RefBase
提供了以下方法:
incStrong(const void* id)
:增加強引用計數。decStrong(const void* id)
:減少強引用計數。getStrongCount()
:獲取當前的強引用計數。
簡單示例代碼
以下是一個完整的例子,演示如何使用 android::sp
和 RefBase
。
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <iostream>using namespace android;// 一個繼承自 RefBase 的類
class MyClass : public RefBase {
public:MyClass() {std::cout << "MyClass Constructor" << std::endl;}~MyClass() {std::cout << "MyClass Destructor" << std::endl;}void display() {std::cout << "Hello from MyClass!" << std::endl;}
};int main() {// 創建智能指針sp<MyClass> sp1 = new MyClass();sp1->display();{// 創建另一個智能指針,引用同一個對象sp<MyClass> sp2 = sp1;std::cout << "sp2 created, reference count: " << sp2->getStrongCount() << std::endl;} // sp2 離開作用域,引用計數減少std::cout << "sp2 out of scope, reference count: " << sp1->getStrongCount() << std::endl;// 離開主作用域,sp1 被銷毀,引用計數為 0,對象銷毀return 0;
}
輸出結果
運行上面的代碼,輸出類似以下內容:
MyClass Constructor
Hello from MyClass!
sp2 created, reference count: 2
sp2 out of scope, reference count: 1
MyClass Destructor
代碼詳解
-
sp<MyClass> sp1 = new MyClass();
sp
是一個模板類,sp<MyClass>
表示一個指向MyClass
的智能指針。- 使用
new
創建一個MyClass
對象,sp1
的構造函數會自動增加引用計數。
-
sp<MyClass> sp2 = sp1;
- 將
sp1
賦值給sp2
,它們會共享同一個MyClass
對象,引用計數增加到 2。
- 將
-
sp2
離開作用域- 當
sp2
離開作用域時,析構函數會減少引用計數(調用decStrong
),此時引用計數變為 1。
- 當
-
sp1
離開作用域- 當
sp1
離開作用域時,引用計數變為 0,MyClass
對象被銷毀(調用析構函數)。
- 當
注意事項
-
對象必須繼承
RefBase
:sp
的引用計數功能依賴于RefBase
,如果對象沒有繼承RefBase
,則不能使用sp
。
-
避免循環引用:
- 如果兩個對象互相持有
sp
指針,會導致引用計數永遠無法歸零,產生內存泄漏。可以使用wp
(弱指針)解決這個問題。
- 如果兩個對象互相持有
擴展:使用弱指針
如果你需要避免循環引用,可以使用 android::wp
(弱指針)。以下是一個簡單示例:
#include <utils/RefBase.h>
#include <iostream>using namespace android;class MyClass : public RefBase {
public:MyClass() {std::cout << "MyClass Constructor" << std::endl;}~MyClass() {std::cout << "MyClass Destructor" << std::endl;}void display() {std::cout << "Hello from MyClass!" << std::endl;}
};int main() {sp<MyClass> sp1 = new MyClass();wp<MyClass> wp1 = sp1; // 創建一個弱指針{sp<MyClass> sp2 = wp1.promote(); // 從弱指針提升為強指針if (sp2 != nullptr) {sp2->display();}} // sp2 離開作用域sp1 = nullptr; // 強引用計數歸零,對象銷毀if (wp1.promote() == nullptr) {std::cout << "Object already destroyed!" << std::endl;}return 0;
}
總結
android::sp
是 Android 中的智能指針,用于管理派生自RefBase
的對象。- 它通過引用計數實現內存管理,避免手動
new
和delete
。 - 使用
sp
時要注意避免循環引用,可以結合wp
使用。