激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - 關于c++ 智能指針及 循環引用的問題

關于c++ 智能指針及 循環引用的問題

2021-04-26 15:43C++教程網 C/C++

下面小編就為大家帶來一篇關于c++ 智能指針及 循環引用的問題。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

c++智能指針介紹

由于 C++ 語言沒有自動內存回收機制,程序員每次 new 出來的內存都要手動 delete,比如流程太復雜,最終導致沒有 delete,異常導致程序過早退出,沒有執行 delete 的情況并不罕見,并造成內存泄露。如此c++引入 智能指針 ,智能指針即是C++ RAII的一種應用,可用于動態資源管理,資源即對象的管理策略。 智能指針在 <memory>標頭文件的 std 命名空間中定義。 它們對 RAII 或 獲取資源即初始化 編程慣用法至關重要。 RAII 的主要原則是為所有堆分配資源提供所有權,例如動態分配內存或系統對象句柄、析構函數包含要刪除或釋放資源的代碼的堆棧分配對象,以及任何相關清理代碼。

c++智能指針類別

c++ 智能指針主要包括:unique_ptr,shared_ptr, weak_ptr, 這三種,其中auto_ptr 已被遺棄。

unique_ptr

只允許基礎指針的一個所有者。 可以移到新所有者(具有移動語義),但不會復制或共享(即我們無法得到指向同一個對象的兩個unique_ptr)。 替換已棄用的 auto_ptr。 相較于 boost::scoped_ptr。 unique_ptr 小巧高效;大小等同于一個指針,支持 rvalue 引用,從而可實現快速插入和對 STL 集合的檢索。 頭文件:<memory>。

使用unique_ptr,可以實現以下功能:

1、為動態申請的內存提供異常安全。
2、將動態申請內存的所有權傳遞給某個函數。
3、從某個函數返回動態申請內存的所有權。
4、在容器中保存指針。
5、所有auto_ptr應該具有的(但無法在C++ 03中實現的)功能。

如下代碼所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A;
// 如果程序執行過程中拋出了異常,unique_ptr就會釋放它所指向的對象
// 傳統的new 則不行
unique_ptr<A> fun1()
{
 unique_ptr p(new A);
 //do something
 return p;
}
 
void fun2()
// unique_ptr具有移動語義
 unique_ptr<A> p = f();// 使用移動構造函數
 // do something
}// 在函數退出的時候,p以及它所指向的對象都被刪除釋放 shared_ptr

 


采用引用計數的智能指針。 shared_ptr基于“引用計數”模型實現,多個shared_ptr可指向同一個動態對象,并維護了一個共享的引用計數器,記錄了引用同一對象的shared_ptr實例的數量。當最后一個指向動態對象的shared_ptr銷毀時,會自動銷毀其所指對象(通過delete操作符)。shared_ptr的默認能力是管理動態內存,但支持自定義的Deleter以實現個性化的資源釋放動作。頭文件:<memory>。

基本操作:shared_ptr的創建、拷貝、綁定對象的變更(reset)、shared_ptr的銷毀(手動賦值為nullptr或離開作用域)、指定deleter等操作。

shared_ptr的創建,有兩種方式,

一,使用函數make_shared(會根據傳遞的參數調用動態對象的構造函數);

二,使用構造函數(可從原生指針、unique_ptr、另一個shared_ptr創建)

shared_ptr<int> p1 = make_shared<int>(1);// 通過make_shared函數

shared_ptr<int> p2(new int(2));// 通過原生指針構造此外智能指針若為“空“,即不指向任何對象,則為false,否則為true,可作為條件判斷。可以通過兩種方式指定deleter,一是構造shared_ptr時,二是使用reset方法時??梢灾剌d的operator->, operator *,以及其他輔助操作如unique()、use_count(), get()等成員方法。

weak_ptr

結合 shared_ptr 使用的特例智能指針。 weak_ptr 提供對一個或多個 shared_ptr 實例所屬對象的訪問,但是,不參與引用計數。 如果您想要觀察對象但不需要其保持活動狀態,請使用該實例。 在某些情況下需要斷開 shared_ptr 實例間的循環引用。 頭文件:<memory>。

weak_ptr的用法如下:

weak_ptr用于配合shared_ptr使用,并不影響動態對象的生命周期,即其存在與否并不影響對象的引用計數器。weak_ptr并沒有重載operator->和operator *操作符,因此不可直接通過weak_ptr使用對象。提供了expired()與lock()成員函數,前者用于判斷weak_ptr指向的對象是否已被銷毀,后者返回其所指對象的shared_ptr智能指針(對象銷毀時返回”空“shared_ptr)。循環引用的場景:如二叉樹中父節點與子節點的循環引用,容器與元素之間的循環引用等。

智能指針的循環引用

循環引用問題可以參考 這個鏈接 上的問題理解,“循環引用”簡單來說就是:兩個對象互相使用一個shared_ptr成員變量指向對方的會造成循環引用。導致引用計數失效。下面給段代碼來說明循環引用:

?
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
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <memory>
using namespace std;
 
class B;
class A
{
public:// 為了省去一些步驟這里 數據成員也聲明為public
 //weak_ptr<B> pb;
 shared_ptr<B> pb;
 void doSomthing()
 {
// if(pb.lock())
// {
//
// }
 }
 
 ~A()
 {
 cout << "kill A\n";
 }
};
 
class B
{
public:
 //weak_ptr<A> pa;
 shared_ptr<A> pa;
 ~B()
 {
 cout <<"kill B\n";
 }
};
 
int main(int argc, char** argv)
{
 shared_ptr<A> sa(new A());
 shared_ptr<B> sb(new B());
 if(sa && sb)
 {
 sa->pb=sb;
 sb->pa=sa;
 }
 cout<<"sa use count:"<<sa.use_count()<<endl;
 return 0;
}

 

上面的代碼運行結果為:sa use count:2, 注意此時sa,sb都沒有釋放,產生了內存泄露問題?。?!

即A內部有指向B,B內部有指向A,這樣對于A,B必定是在A析構后B才析構,對于B,A必定是在B析構后才析構A,這就是循環引用問題,違反常規,導致內存泄露。

一般來講,解除這種循環引用有下面有三種可行的方法( 參考 ):

1 . 當只剩下最后一個引用的時候需要手動打破循環引用釋放對象。

2 . 當A的生存期超過B的生存期的時候,B改為使用一個普通指針指向A。

3 . 使用弱引用的智能指針打破這種循環引用。

雖然這三種方法都可行,但方法1和方法2都需要程序員手動控制,麻煩且容易出錯。我們一般使用第三種方法:弱引用的智能指針weak_ptr。

強引用和弱引用

一個強引用當被引用的對象活著的話,這個引用也存在(就是說,當至少有一個強引用,那么這個對象就不能被釋放)。share_ptr就是強引用。相對而言,弱引用當引用的對象活著的時候不一定存在。僅僅是當它存在的時候的一個引用。弱引用并不修改該對象的引用計數,這意味這弱引用它并不對對象的內存進行管理,在功能上類似于普通指針,然而一個比較大的區別是,弱引用能檢測到所管理的對象是否已經被釋放,從而避免訪問非法內存。

使用weak_ptr來打破循環引用

代碼如下:

?
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
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <memory>
using namespace std;
 
class B;
class A
{
public:// 為了省去一些步驟這里 數據成員也聲明為public
 weak_ptr<B> pb;
 //shared_ptr<B> pb;
 void doSomthing()
 {
 if(pb.lock())
 {
 
 }
 }
 
 ~A()
 {
 cout << "kill A\n";
 }
};
 
class B
{
public:
 //weak_ptr<A> pa;
 shared_ptr<A> pa;
 ~B()
 {
 cout <<"kill B\n";
 }
};
 
int main(int argc, char** argv)
{
 shared_ptr<A> sa(new A());
 shared_ptr<B> sb(new B());
 if(sa && sb)
 {
 sa->pb=sb;
 sb->pa=sa;
 }
 cout<<"sb use count:"<<sb.use_count()<<endl;
 return 0;
}

以上就是小編為大家帶來的關于c++ 智能指針及 循環引用的問題全部內容了,希望大家多多支持服務器之家~

延伸 · 閱讀

精彩推薦
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
主站蜘蛛池模板: 99精品视频在线观看免费播放 | 成人情欲视频在线看免费 | 精品国产一区二区三区久久久 | 黄色网址入口 | 草久网 | 五月激情久久 | 视频一区二区三区在线播放 | 午夜视频在线免费播放 | 欧美女同hd | 国产亚洲在线 | 99ri在线观看 | 娇妻被各种姿势c到高潮小说 | 91成人久久 | 韩国精品视频在线观看 | 成人在线免费视频播放 | 久久国产精品久久久久 | 欧美国产日韩在线观看成人 | 免费黄色在线电影 | 欧美一级网站 | 一级黄色免费 | 国产亚洲欧美日韩高清 | 男人午夜视频 | 久久免费视频7 | 亚洲3atv精品一区二区三区 | 国产99一区二区 | 日韩视频在线免费 | 久久久久久久久浪潮精品 | 精品亚洲夜色av98在线观看 | 日韩黄色免费观看 | 高潮娇喘嗯啊~文字 | 日韩欧美高清片 | 中文字幕在线观看网址 | 欧美大荫蒂xxx | 一级黄色免费观看 | 欧美 日韩 三区 | 在线看一区二区三区 | 亚洲一区在线视频观看 | 国产精品成人免费一区久久羞羞 | 成人免费国产视频 | 中文字幕在线播放视频 | 日本一区二区视频在线观看 |