作為智能指針的一種,unique_ptr 指針自然也具備“在適當時機自動釋放堆內存空間”的能力。和 shared_ptr 指針最大的不同之處在於,unique_ptr 指針指向的堆內存無法同其它 unique_ptr 共享,也就是說,每個 unique_ptr 指針都獨自擁有對其所指堆內存空間的所有權。
unique_ptr 智能指針是以模板類的形式提供的,unique_ptr<T>(T 為指針所指數據的類型)定義在這也就意味着,每個 unique_ptr 指針指向的堆內存空間的引用計數,都只能為 1,一旦該 unique_ptr 指針放棄對所指堆內存空間的所有權,則該空間會被立即釋放回收。
<memory>頭文件,並位於 std 命名空間中。因此,要想使用 unique_ptr 類型指針,程序中應首先包含如下 2 條語句:
- #include <memory>
- using namespace std;
第 2 句並不是必須的,可以不添加,則后續在使用 unique_ptr 指針時,必須標注
std::。
unique_ptr智能指針的創建
考慮到不同實際場景的需要,unique_ptr<T> 模板類提供了多個實用的構造函數,這里給讀者列舉了幾種常用的構造 unique_ptr 智能指針的方式。1) 通過以下 2 種方式,可以創建出空的 unique_ptr 指針:
- std::unique_ptr<int> p1();
- std::unique_ptr<int> p2(nullptr);
2) 創建 unique_ptr 指針的同時,也可以明確其指向。例如:
- std::unique_ptr<int> p3(new int);
和可以用 make_shared<T>() 模板函數初始化 shared_ptr 指針不同,C++11 標准中並沒有為 unique_ptr 類型指針添加類似的模板函數。
3) 基於 unique_ptr 類型指針不共享各自擁有的堆內存,因此 C++11 標准中的 unique_ptr 模板類沒有提供拷貝構造函數,只提供了移動構造函數。例如:
- std::unique_ptr<int> p4(new int);
- std::unique_ptr<int> p5(p4);//錯誤,堆內存不共享
- std::unique_ptr<int> p5(std::move(p4));//正確,調用移動構造函數
4) 默認情況下,unique_ptr 指針采用 std::default_delete<T> 方法釋放堆內存。當然,我們也可以自定義符合實際場景的釋放規則。值得一提的是,和 shared_ptr 指針不同,為 unique_ptr 自定義釋放規則,只能采用函數對象的方式。例如:
- //自定義的釋放規則
- struct myDel
- {
- void operator()(int *p) {
- delete p;
- }
- };
- std::unique_ptr<int, myDel> p6(new int);
- //std::unique_ptr<int, myDel> p6(new int, myDel());
unique_ptr<T>模板類提供的成員方法
為了方便用戶使用 unique_ptr 智能指針,unique_ptr<T> 模板類還提供有一些實用的成員方法,它們各自的功能如表 1 所示。| 成員函數名 | 功 能 |
|---|---|
| operator*() | 獲取當前 unique_ptr 指針指向的數據。 |
| operator->() | 重載 -> 號,當智能指針指向的數據類型為自定義的結構體時,通過 -> 運算符可以獲取其內部的指定成員。 |
| operator =() | 重載了 = 賦值號,從而可以將 nullptr 或者一個右值 unique_ptr 指針直接賦值給當前同類型的 unique_ptr 指針。 |
| operator []() | 重載了 [] 運算符,當 unique_ptr 指針指向一個數組時,可以直接通過 [] 獲取指定下標位置處的數據。 |
| get() | 獲取當前 unique_ptr 指針內部包含的普通指針。 |
| get_deleter() | 獲取當前 unique_ptr 指針釋放堆內存空間所用的規則。 |
| operator bool() | unique_ptr 指針可直接作為 if 語句的判斷條件,以判斷該指針是否為空,如果為空,則為 false;反之為 true。 |
| release() | 釋放當前 unique_ptr 指針對所指堆內存的所有權,但該存儲空間並不會被銷毀。 |
| reset(p) | 其中 p 表示一個普通指針,如果 p 為 nullptr,則當前 unique_ptr 也變成空指針;反之,則該函數會釋放當前 unique_ptr 指針指向的堆內存(如果有),然后獲取 p 所指堆內存的所有權(p 為 nullptr)。 |
| swap(x) | 交換當前 unique_ptr 指針和同類型的 x 指針。 |
除此之外,C++11標准還支持同類型的 unique_ptr 指針之間,以及 unique_ptr 和 nullptr 之間,做 ==,!=,<,<=,>,>= 運算。
下面程序給大家演示了 unique_ptr 智能指針的基本用法,以及該模板類提供了一些成員方法的用法:
- #include <iostream>
- #include <memory>
- using namespace std;
- int main()
- {
- std::unique_ptr<int> p5(new int);
- *p5 = 10;
- // p 接收 p5 釋放的堆內存
- int * p = p5.release();
- cout << *p << endl;
- //判斷 p5 是否為空指針
- if (p5) {
- cout << "p5 is not nullptr" << endl;
- }
- else {
- cout << "p5 is nullptr" << endl;
- }
- std::unique_ptr<int> p6;
- //p6 獲取 p 的所有權
- p6.reset(p);
- cout << *p6 << endl;;
- return 0;
- }
10
p5 is nullptr
10
------------------------------ 上面有誤-------------
std::unique_ptr::release
pointer release() noexcept;
Releases ownership of its stored pointer, by returning its value and replacing it with a null pointer.
This call does not destroy the managed object, but the unique_ptr object is released from the responsibility of deleting the object. Some other entity must take responsibility for deleting the object at some point.
To force the destruction of the object pointed, either use member function reset or perform an assignment operation on it.
Parameters
none
Return value
A pointer to the object managed by unique_ptr before the call.
pointer is a member type, defined as the pointer type that points to the type of object managed.
Example
|
|
Output:
manual_pointer points to 10 |
See also
- unique_ptr::reset
- Reset pointer (public member function )
- unique_ptr::get
- Get pointer (public member function )
- unique_ptr::operator=
- unique_ptr assignment (public member function )
