C++ std::weak_ptr 用法與範例

本篇 ShengYu 將介紹 C++ 的 std::weak_ptr 用法,

需要引入的標頭檔<memory>,編譯需要支援 C++11

weak_ptr 檢查參考的物件是否過期

用 weak_ptr 檢查參考的物件是否過期,如果該物件被釋放 (delete) 的話那麼表示已過期,

如下列範例所示,將 Size 物件從 shared_ptr 建立 weak_ptr wp 後,可以發現 wp.use_count() 是 1 不是 2,這時用 wp.expired() 來檢查是否過期,結果顯示還沒過期,接著將原本的 shared_ptr sp 指向 nullptr,那麼 reference count 降為 0 後 Size 物件會被 delete,接著再次使用 wp.expired() 來檢查是否過期,結果顯示已過期了,

std-std-weak_ptr.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// g++ std-std-weak_ptr.cpp -o a.out -std=c++11
#include <iostream>
#include <memory>

using namespace std;

class Size {
public:
Size() {}
Size(int w, int h) : width(w), height(h) {}

int width = 0;
int height = 0;
};

int main() {
shared_ptr<Size> sp = make_shared<Size>(10, 20);
weak_ptr<Size> wp(sp);

cout << wp.use_count() << "\n";

if (wp.expired()) { // 如果 wp 沒有指向任何物件的話
cout << "wp was expired\n";
} else {
cout << "wp does not expire\n";
}

sp = nullptr; // reference count 降為 0,Size 物件被 delete

if (wp.expired()) { // 如果 wp 沒有指向任何物件的話
cout << "wp was expired\n";
} else {
cout << "wp does not expire\n";
}

return 0;
}

輸出如下,

1
2
3
1
wp does not expire
wp was expired

從 weak_ptr 轉 shared_ptr

weak_ptr 轉 shared_ptr 有兩種方式,一種是使用 weak_ptr.lock,如果該物件還沒被釋放的話可以成功的轉換成 shared_ptr,如果該物件被釋放的話則會回傳 nullptr,

1
shared_ptr<Size> sp = wp.lock();

另一種方式是使用 shared_ptr 的建構子,

1
shared_ptr<Size> sp(wp);

其它參考
std::weak_ptr - cppreference.com
https://en.cppreference.com/w/cpp/memory/weak_ptr

其它相關文章推薦
C/C++ 新手入門教學懶人包
std::unique_ptr 用法與範例
std::shared_ptr 用法與範例