成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊智能指針和所有權(quán)的問(wèn)題

開(kāi)發(fā) 后端
在編程語(yǔ)言中,對(duì)堆對(duì)象的內(nèi)存管理是一個(gè)麻煩又復(fù)雜的問(wèn)題。一不小心就會(huì)帶來(lái)問(wèn)題,本文簡(jiǎn)單探討一下關(guān)于對(duì)象所有權(quán)的問(wèn)題。

[[414238]]

在編程語(yǔ)言中,對(duì)堆對(duì)象的內(nèi)存管理是一個(gè)麻煩又復(fù)雜的問(wèn)題。一不小心就會(huì)帶來(lái)問(wèn)題,比如JS里一直引用一個(gè)已經(jīng)不使用的對(duì)象導(dǎo)致gc無(wú)法回收,或者C++里多個(gè)變量指向同一塊內(nèi)存導(dǎo)致重復(fù)釋放。本文簡(jiǎn)單探討一下關(guān)于對(duì)象所有權(quán)的問(wèn)題。

對(duì)象的所有權(quán)意味著當(dāng)我們分配一個(gè)對(duì)象的時(shí)候,誰(shuí)持有這個(gè)對(duì)象的所有權(quán),比如下面代碼。

  1. Object *obj = new Object(); 

那么obj就持有了對(duì)象的所有權(quán)。但是現(xiàn)實(shí)往往比較復(fù)雜,比如我們看看下面代碼。

  1. #include<stdio.h> 
  2. using namespace std; 
  3.  
  4.  
  5.  
  6. class Demo { 
  7.     public
  8.     ~Demo(){ 
  9.         printf("執(zhí)行析構(gòu)函數(shù)"); 
  10.     }};void test() { 
  11.     Demo *d = new Demo(); 
  12.  
  13.  
  14.  
  15.  
  16. int main(){ 
  17.  
  18.    test(); 
  19.    return 0; 
  20.  

執(zhí)行上面的代碼,我們?cè)趖est函數(shù)里分配一個(gè)堆對(duì)象,執(zhí)行完test后我們發(fā)現(xiàn)Demo對(duì)象的析構(gòu)函數(shù)并沒(méi)有執(zhí)行,這就造成了內(nèi)存泄漏。那我們需要怎么做呢?我們需要收到釋放對(duì)象對(duì)應(yīng)的內(nèi)存。修改一下test函數(shù)的代碼。

  1. void test() { 
  2.     Demo *d = new Demo(); 
  3.     delete d; 
  4.  

這時(shí)候我們發(fā)現(xiàn)就會(huì)輸出執(zhí)行析構(gòu)函數(shù)幾個(gè)字了,說(shuō)明析構(gòu)函數(shù)被執(zhí)行,對(duì)象的內(nèi)存也被釋放了。手動(dòng)管理內(nèi)存不僅麻煩,而且往往容易出錯(cuò),比如我們往往會(huì)忘了釋放,尤其是代碼邏輯復(fù)雜的時(shí)候。這時(shí)候,我們可以使用智能指針解決這個(gè)問(wèn)題。

  1. #include <iostream> 
  2.  
  3. #include<stdio.h> 
  4.  
  5.  
  6.  
  7. using namespace std; 
  8.  
  9.  
  10.  
  11. class Demo { 
  12.     public
  13.     ~Demo(){ 
  14.         printf("執(zhí)行析構(gòu)函數(shù)"); 
  15.     } 
  16.  
  17. }; 
  18.  
  19.  
  20. template<class T> 
  21. class SmartPoint 
  22.     T* point; 
  23. public
  24.     SmartPoint(T *ptr = nullptr) :point(ptr) {} 
  25.  
  26.     ~SmartPoint() { 
  27.         if (point) { 
  28.             // 會(huì)調(diào)用point指向?qū)ο蟮牡奈鰳?gòu)函數(shù) 
  29.             delete point; 
  30.         } 
  31.     } 
  32.     // 使用智能指針就像使用內(nèi)部包裹的的對(duì)象一樣 
  33.     T& operator*() {  
  34.         return *point;  
  35.     } 
  36.  
  37.     T* operator->() {  
  38.         return point;  
  39.     } 
  40.  
  41. }; 
  42.  
  43.  
  44.  
  45. void test() { 
  46.  
  47.     SmartPoint<Demo> p(new Demo()); 
  48.  
  49.  
  50.  
  51.  
  52. int main(){ 
  53.  
  54.    test(); 
  55.    return 0; 
  56.  

智能指針的原理比較簡(jiǎn)單,因?yàn)橹悄苤羔槍?duì)象是在棧上面分配的,離開(kāi)作用域的時(shí)候會(huì)被自動(dòng)釋放,然后在智能指針的析構(gòu)函數(shù)里釋放包裹的內(nèi)部對(duì)象。看起來(lái)是很完美的解決方案。但是智能指針也帶來(lái)了一些問(wèn)題,那就是在復(fù)制或賦值的時(shí)候。我們看看代碼。

  1. int main(){ 
  2.    SmartPoint<Demo> p(new Demo()); 
  3.    SmartPoint<Demo> p2 = p; 
  4.    return 0; 
  5.  

執(zhí)行下面代碼會(huì)導(dǎo)致core dump,為什么呢?我們來(lái)看看這個(gè)過(guò)程。當(dāng)執(zhí)行p2=p的時(shí)候會(huì)導(dǎo)致p2和p的內(nèi)部指針point都指向了Demo對(duì)象的地址,最后代碼執(zhí)行完畢后,兩個(gè)智能指針都執(zhí)行了釋放內(nèi)存的操作,重復(fù)釋放內(nèi)存導(dǎo)致了core dump。那如何解決這個(gè)問(wèn)題呢?一種方式是復(fù)制一份point指向的內(nèi)存,但是我們可能不知道這個(gè)內(nèi)存多大,無(wú)法復(fù)制,另一種方式就是所有權(quán)轉(zhuǎn)移。我們繼續(xù)看代碼。

  1. #include <iostream> 
  2.  
  3. #include<stdio.h> 
  4.  
  5.  
  6.  
  7. using namespace std; 
  8.  
  9.  
  10.  
  11. class Demo { 
  12.     public
  13.     ~Demo(){ 
  14.         printf("執(zhí)行析構(gòu)函數(shù)"); 
  15.     } 
  16.  
  17. }; 
  18.  
  19.  
  20. template<class T> 
  21. class SmartPoint 
  22.     T* point; 
  23. public
  24.     SmartPoint(T *ptr = nullptr) :point(ptr) {} 
  25.     // 實(shí)現(xiàn)復(fù)制構(gòu)造函數(shù) 
  26.     SmartPoint(SmartPoint & p) {  
  27.         // 指向p.point對(duì)應(yīng)的內(nèi)存 
  28.         point = p.point; 
  29.         // p.point置null 
  30.         p.point = nullptr; 
  31.     } 
  32.     ~SmartPoint() { 
  33.         if (point) { 
  34.             // 會(huì)調(diào)用point指向?qū)ο蟮牡奈鰳?gòu)函數(shù) 
  35.             delete point; 
  36.         } 
  37.     } 
  38.     // 使用智能指針就像使用內(nèi)部包裹的的對(duì)象一樣 
  39.     T& operator*() {  
  40.         return *point;  
  41.     } 
  42.  
  43.     T* operator->() {  
  44.         return point;  
  45.     } 
  46.  
  47. }; 
  48.  
  49.  
  50.  
  51. int main(){ 
  52.  
  53.    SmartPoint<Demo> p(new Demo()); 
  54.    SmartPoint<Demo> p2 = p; 
  55.    return 0; 
  56.  

我們實(shí)現(xiàn)了一個(gè)復(fù)制構(gòu)造函數(shù),在main里執(zhí)行p2=p時(shí)會(huì)被執(zhí)行,在復(fù)制構(gòu)造函數(shù)中,我們實(shí)現(xiàn)了所有權(quán)轉(zhuǎn)移,這時(shí)候p2時(shí)Demo對(duì)象的持有者,而p指向null,這時(shí)候不能再對(duì)p進(jìn)行操作。這時(shí)候我們可以在SmartPoint中實(shí)現(xiàn)一個(gè)isNull函數(shù)用于判斷智能指針的有效性。

  1. bool isNull() { 
  2.     return point == nullptr;  

然后在使用的地方加一下判斷。

  1. if (p.isNull()) { 
  2.     //  
  3.  

這顯然很麻煩。我們看看Rust怎么做。

  1. struct Demo(u32); 
  2.  
  3. fn main() { 
  4.     let _box1 = Box::new(Demo(1)); 
  5.     // 所有權(quán)轉(zhuǎn)移 
  6.     let _box2 = _box1; 
  7.     // 報(bào)錯(cuò) 
  8.     println!("{}", _box1.0); 
  9.  

 編譯上面代碼會(huì)報(bào)錯(cuò),是編譯而不是運(yùn)行,這就是Rust,在編譯期就解決了這個(gè)問(wèn)題。Box是智能指針,以上代碼和剛才C++中的代碼類似,當(dāng)執(zhí)行_box2=_box1的時(shí)候,堆對(duì)象的所有權(quán)就轉(zhuǎn)移到了_box2,_box1相當(dāng)于包裹了一個(gè)空指針,而Rust不允許你再訪問(wèn)_box1管理里的內(nèi)存。

 

責(zé)任編輯:姜華 來(lái)源: 編程雜技
相關(guān)推薦

2011-01-07 09:19:35

Linux文件權(quán)限

2024-03-19 14:43:55

Rust編譯所有權(quán)

2024-09-02 10:40:18

2017-07-27 13:34:52

Rust所有權(quán)數(shù)據(jù)

2023-10-10 11:04:11

Rust難點(diǎn)內(nèi)存

2022-11-03 15:14:43

Linux文件權(quán)限

2022-03-18 08:00:00

區(qū)塊鏈代幣以太坊

2024-01-10 09:26:52

Rust所有權(quán)編程

2011-01-20 07:50:51

Linux文件系統(tǒng)管理所有權(quán)

2009-11-28 20:21:14

2011-03-03 15:40:55

PureFTPd

2013-08-16 10:46:20

2015-07-27 11:34:03

Linux內(nèi)核指針

2022-05-30 00:19:13

元宇宙NFTWeb3

2022-08-11 10:42:58

Rust

2021-08-11 09:01:48

智能指針Box

2018-01-23 11:15:28

云計(jì)算數(shù)據(jù)平臺(tái)云平臺(tái)

2018-12-14 10:08:23

物聯(lián)網(wǎng)訂閱IOT

2009-09-12 09:46:47

Windows 7所有權(quán)添加

2017-10-23 12:42:42

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产成人网| 久久久久久久久久久久久9999 | 99久久99热这里只有精品 | 中文字幕精品一区久久久久 | 一级片在线视频 | 成人免费区一区二区三区 | 亚洲中午字幕 | 久久精品久久久久久 | 99久久久无码国产精品 | 精品丝袜在线 | 视频一区二区中文字幕日韩 | 玖玖精品 | 精品视频一区二区三区在线观看 | 欧美一区二区三区四区视频 | aaa级片| 国产偷录叫床高潮录音 | 一区二区三区电影网 | 夜夜精品视频 | 人人人人爽| 最新91在线 | 国产在线中文字幕 | 成人在线中文字幕 | 午夜免费观看网站 | 久久久久久一区 | 国产精品精品视频一区二区三区 | 色综合久久88色综合天天 | 一区二区三区国产精品 | 在线免费黄色小视频 | av免费网站在线观看 | 在线视频一区二区 | 国产免费观看一级国产 | 日韩欧美在线视频观看 | 国产一区免费视频 | 欧美一区二区大片 | 国产视频1区2区 | 中文字幕免费观看 | 密室大逃脱第六季大神版在线观看 | 日韩高清一区 | 国产一级免费视频 | 天天曰夜夜操 | 日本黄色一级视频 |