国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看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方法時。可以重載的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
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 五月婷婷在线观看 | 中文久久久久久 | 久久五月视频 | 亚洲国产91 | 色综合成人 | 亚洲视频在线播放免费 | 国产一区二区欧美 | 欧美成人精品一区二区三区 | 黑人精品| 欧美中文字幕一区二区三区亚洲 | 欧美成人免费视频 | 欧美精品第一页 | 日韩精品在线一区 | 中国黄色片在线观看 | 国产亚洲精品久久久 | 日韩成人小视频 | 精品久久久久久久人人人人传媒 | 在线观看亚洲精品 | 日韩在线综合 | 色吧av | 国产精品午夜电影 | 欧美顶级毛片在线播放 | 精品久久一二三区 | 国产精品一码二码三码在线 | 在线观看日韩av | 色天堂影院 | av网站大全免费 | 狠狠干av | 黄色av电影 | 亚洲国产一区二区三区精品 | 91久久久久久久久 | 在线观看a毛片 | 亚洲综合国产 | 免费一级片 | 久久久久久综合 | 蜜臀久久精品99国产精品日本 | 国内免费自拍视频 | 国产色爱综合网 | 亚洲欧美日韩在线 | a天堂中文在线观看 | 久草在线新视觉 |