作者:Arthurian https://www.cnblogs.com/Arthurian/p/17407347.html
智能指針是C++語言中一種方便、安全的內存管理工具。智能指針可以自動管理對象的生命周期,避免手動分配和釋放內存時可能出現的內存泄漏和懸掛指針等問題。在C++11標準中,引入了三種智能指針:unique_ptr、shared_ptr 和 weak_ptr。
unique_ptr 是一種獨占式智能指針,它擁有對一個對象的唯一所有權,不能與其他智能指針共享對象所有權。當 unique_ptr 超出范圍或被顯式釋放時,它所擁有的對象會被自動銷毀。
shared_ptr 是一種共享式智能指針,它可以與其他 shared_ptr 共享一個對象。shared_ptr 使用引用計數技術來記錄有多少個 shared_ptr 指向同一個對象,當引用計數為0時,對象會被自動銷毀。
weak_ptr 是一種弱引用智能指針,它指向一個由 shared_ptr 管理的對象,但不會增加對象的引用計數。weak_ptr 用于解決循環引用問題,例如兩個對象相互引用,導致它們的引用計數永遠不會為0,從而無法自動銷毀。
使用智能指針可以大大簡化內存管理,減少內存泄漏和懸掛指針等問題。同時,智能指針還可以幫助程序員更好地編寫多線程程序,避免競態條件等問題。
下面是一個簡單的示例程序,演示了如何使用 unique_ptr 和 shared_ptr:
1 #include <iostream>
2 #include <memory>
3
4 struct Foo {
5 Foo() { std::cout << "Foo::Foo\n"; }
6 ~Foo() { std::cout << "Foo::~Foo\n"; }
7 };
8
9 int main() {
10 std::unique_ptr<Foo> p1(new Foo); // 使用 unique_ptr 管理 Foo 對象的生命周期
11 {
12 std::shared_ptr<Foo> p2 = std::make_shared<Foo>(); // 使用 shared_ptr 管理 Foo 對象的生命周期
13 {
14 std::shared_ptr<Foo> p3 = p2; // p2 和 p3 共享 Foo 對象
15 } // p3 超出范圍,引用計數減1
16 } // p2 超出范圍,引用計數減1,Foo 對象被銷毀
17 // p1 超出范圍,Foo 對象被銷毀
18 return 0;
19 }
在上面的示例程序中,我們創建了一個 Foo 對象,并使用 unique_ptr 和 shared_ptr 來管理它的生命周期。在 p2 和 p3 共享 Foo 對象時,它們的引用計數都為2。當 p3 超出范圍時,引用計數減1;當 p2 超出范圍時,引用計數再減1,Foo 對象被自動銷毀。最后,當 p1 超出范圍時,Foo 對象再次被銷毀。
除了unique_ptr和shared_ptr,C++還有weak_ptr,它是一種不控制對象生命周期的智能指針。它指向一個由shared_ptr管理的對象,但不會增加對象的引用計數。它主要用于解決循環引用問題,例如兩個對象相互引用,導致它們的引用計數永遠不會為0,從而無法自動銷毀。
下面是一個使用weak_ptr的示例程序:
1 #include <iostream>
2 #include <memory>
3
4 struct Foo {
5 void bar() { std::cout << "Foo::bar\n"; }
6 ~Foo() { std::cout << "Foo::~Foo\n"; }
7 };
8
9 int main() {
10 std::shared_ptr<Foo> p1(new Foo); // 使用 shared_ptr 管理 Foo 對象的生命周期
11 std::weak_ptr<Foo> wp1 = p1; // wp1 指向 p1 管理的 Foo 對象,但不增加引用計數
12 {
13 std::shared_ptr<Foo> p2 = wp1.lock(); // 使用 lock() 獲取 shared_ptr
14 if (p2) {
15 p2->bar(); // 如果 p2 不為空,調用 bar() 函數
16 }
17 } // p2 超出范圍,引用計數減1
18 // wp1 超出范圍,因為引用計數已經為0,所以 Foo 對象被銷毀
19 return 0;
20 }
在這個示例程序中,我們創建了一個 Foo 對象,使用 shared_ptr 和 weak_ptr 來管理它的生命周期。weak_ptr 用于解決循環引用問題,因此它不控制對象生命周期。當最后一個擁有該對象的 shared_ptr 不存在時,該對象被自動銷毀。因此,在上面的示例程序中,當 p2 超出范圍時,引用計數減1,Foo 對象將被銷毀。當 wp1 超出范圍時,因為引用計數已經為0,所以 Foo 對象再次被銷毀。
另外,C++還提供了一種名為“std::enable_shared_from_this”的模板類,它允許智能指針在對象的成員函數中獲取對對象的共享所有權。
下面是一個使用std::enable_shared_from_this的示例程序:
1 #include <iostream>
2 #include <memory>
3
4 struct Foo : std::enable_shared_from_this<Foo> {
5 void bar() {
6 std::cout << "Foo::bar\n";
7 auto sptr = shared_from_this();
8 if (sptr) {
9 sptr->baz();
10 }
11 }
12 void baz() {
13 std::cout << "Foo::baz\n";
14 }
15 };
16
17 int main() {
18 std::shared_ptr<Foo> p1(new Foo); // 使用 shared_ptr 管理 Foo 對象的生命周期
19 p1->bar(); // 在 bar() 中使用 enable_shared_from_this 獲取對 Foo 對象的共享所有權,并調用 baz() 函數
20 // p1 超出范圍,引用計數減1,因為 enable_shared_from_this 不增加引用計數
21 // Foo 對象被銷毀
22 return 0;
23 }
在這個示例程序中,我們創建了一個 Foo 對象,使用 shared_ptr 管理它的生命周期,并在它的成員函數 bar() 中使用 enable_shared_from_this 獲取對它的共享所有權。在 bar() 中,我們還調用了另一個成員函數 baz()。當 p1 超出范圍時,引用計數減1,因為 enable_shared_from_this 不增加引用計數,所以 Foo 對象被銷毀。當最后一個擁有該對象的 shared_ptr 不存在時,該對象被自動銷毀。
另外,C++的智能指針還提供了一些功能,如“std::atomic_shared_ptr”和“std::shared_ptr_future”,可以讓你在多線程環境中更安全地使用智能指針。這些功能可以幫助你避免多線程競爭條件等問題。
除此之外,C++還提供了一些更高級的模板庫,如“Boost”和“Qt”,其中包含更多高級的智能指針和內存管理功能。例如,Boost庫中的“boost::interprocess”庫提供了跨進程內存管理和共享訪問等功能。這些高級功能可以讓你更加靈活地管理內存和開發大規模的應用程序。
總之,C++的智能指針是一個非常強大和靈活的內存管理工具。通過使用不同類型的智能指針和遵循RAII原則,你可以在C++程序中更安全、更有效地管理內存和其他資源。
C++ 校招 / 社招跳槽逆襲!從0到1打造高含金量項目,導師1v1輔導,助你斬獲大廠offer!
很多同學準備校招時最焦慮的問題就是:“簡歷沒項目,怎么打動面試官?”
為了解決這個痛點,我們推出了 C++訓練營,來了!

在這里,你可以:
我們不只是教你寫代碼,更帶你走一遍完整的項目流程: 從需求分析、架構設計、編譯調試,到版本管理、測試發布,全流程掌握!
項目配套資料齊全,遇到問題還有導師幫你答疑,不怕卡殼!
項目準備好了,你只差一次出發。
相信我,這些項目絕對能夠讓你進步巨大!下面是其中某三個項目的說明文檔

訓練營適用人群:
不適合人群:

1、C++訓練營,來了!
2、HarmonyOS 學習資料分享(無套路免費分享)
我組建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起進群交流。
歡迎你添加我的微信,我拉你進技術交流群。此外,我也會經常在微信上分享一些計算機學習經驗以及工作體驗,還有一些內推機會。
加個微信,打開另一扇窗
感謝你的分享,點贊,在看三連