一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C/C++ - C++中的auto_ptr智能指針的作用及使用方法詳解

C++中的auto_ptr智能指針的作用及使用方法詳解

2021-04-09 13:482010120422 C/C++

這篇文章主要介紹了C++中的auto_ptr智能指針的作用及使用方法詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

智能指針(auto_ptr) 這個(gè)名字聽(tīng)起來(lái)很酷是不是?其實(shí)auto_ptr 只是C++標(biāo)準(zhǔn)庫(kù)提供的一個(gè)類(lèi)模板,它與傳統(tǒng)的new/delete控制內(nèi)存相比有一定優(yōu)勢(shì),但也有其局限。本文總結(jié)的8個(gè)問(wèn)題足以涵蓋auto_ptr的大部分內(nèi)容。

 auto_ptr是什么?

auto_ptr 是C++標(biāo)準(zhǔn)庫(kù)提供的類(lèi)模板,auto_ptr對(duì)象通過(guò)初始化指向由new創(chuàng)建的動(dòng)態(tài)內(nèi)存,它是這塊內(nèi)存的擁有者,一塊內(nèi)存不能同時(shí)被分給兩個(gè)擁有者。當(dāng)auto_ptr對(duì)象生命周期結(jié)束時(shí),其析構(gòu)函數(shù)會(huì)將auto_ptr對(duì)象擁有的動(dòng)態(tài)內(nèi)存自動(dòng)釋放。即使發(fā)生異常,通過(guò)異常的棧展開(kāi)過(guò)程也能將動(dòng)態(tài)內(nèi)存釋放。auto_ptr不支持new 數(shù)組。

該類(lèi)型在頭文件memory中,在程序的開(kāi)通通過(guò) #include<memory> 導(dǎo)入,接下來(lái)講解該智能指針的作用和使用。

使用方法:

  auto_ptr<type> ptr(new type()); 這是該指針的定義形式,其中 type 是指針指向的類(lèi)型,ptr 是該指針的名稱(chēng)。

  比如該type 是int,具體定義如下:

  auto_ptr<int> ptr(new int(4));

  比如該type 是map<int,vector<int> >,具體定義如下:

  auto_ptr<map<int,vector<int> > > ptr(new map<int,vector<int> > ());

  當(dāng)然可以先定義,后賦值,如下所示:

  auto_ptr<map<int,int> > ptr;
  ptr = auto_ptr<map<int,int> >(new map<int,int> ());

作用1:保證一個(gè)對(duì)象在某個(gè)時(shí)間只能被一個(gè)該種類(lèi)型的智能指針?biāo)赶颍褪峭ǔKf(shuō)的對(duì)象所有權(quán)。

作用2:對(duì)指向的對(duì)象自動(dòng)釋放的作用,詳情看如下代碼。

代碼片段一:

?
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
#include <iostream>
#include <string.h>
#include <memory>
#include <string>
#include <Windows.h>
#include <map>
#include <ctime>
#include <vector>
using namespace std;#define MAXN 20000000
class test_ptr
{
public:
map<int,int> *p;
test_ptr()
{
p = new map<int,int>();
for(int i = 0;i<MAXN;i++)
p->insert(make_pair(i,i));
}
};
int main(int argc,char *argv[])
{
for(int i = 0;i<100;i++)
{
Sleep(1000);
cout << i << endl; // 輸出 創(chuàng)建次數(shù)
test_ptr * tmp = new test_ptr();
}
system("pause");
return 0;
}

 

在某些情況下,可能我們就會(huì)寫(xiě)出上面的代碼來(lái),通過(guò)運(yùn)行會(huì)發(fā)現(xiàn)存在內(nèi)存溢出。對(duì)于一些經(jīng)驗(yàn)老道的程序員可能會(huì)作如下改寫(xiě):

代碼片段二:

?
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
#include <iostream>
#include <string.h>
#include <memory>
#include <string>
#include <Windows.h>
#include <map>
#include <ctime>
#include <vector>
using namespace std;
#define MAXN 20000000
class test_ptr
{
public:
map<int,int> *p;
test_ptr()
{
//p = auto_ptr<map<int,int> > (new map<int,int>());
p = new map<int,int>();
for(int i = 0;i<MAXN;i++)
p->insert(make_pair(i,i));
}
~test_ptr()
{
delete p;
}
};
int main(int argc,char *argv[])
{
for(int i = 0;i<100;i++)
{
Sleep(1000);
cout << i << endl;
test_ptr * tmp = new test_ptr();
}
system("pause");
return 0;
}

在test_ptr 類(lèi)中的析構(gòu)函數(shù)中添加內(nèi)存釋放代碼,但是在main函數(shù)中,定義的局部指針,當(dāng)局部指針失效時(shí)并不會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),在這種情況下也會(huì)導(dǎo)致內(nèi)存泄漏問(wèn)題。當(dāng)然,如果細(xì)心的程序員可以在 test_ptr * tmp = new test_ptr() 后面加上一句 delete tmp ,這樣也能夠釋放內(nèi)存,不會(huì)出現(xiàn)內(nèi)存泄漏問(wèn)題。但是在某些情況下,很容易漏寫(xiě),為了解決此問(wèn)題,auto_ptr 就能發(fā)揮作用了。

代碼片段三:

?
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
#include <iostream>
#include <string.h>
#include <memory>
#include <string>
#include <Windows.h>
#include <map>
#include <ctime>
#include <vector>
using namespace std;
#define MAXN 20000000
class test_ptr
{
public:
map<int,int> *p;
test_ptr()
{
p = new map<int,int>();
for(int i = 0;i<MAXN;i++)
p->insert(make_pair(i,i));
}
~test_ptr()
{
delete p;
}
};
int main(int argc,char *argv[])
{
for(int i = 0;i<100;i++)
{
Sleep(1000);
cout << i << endl; //輸出創(chuàng)建次數(shù)
auto_ptr<test_ptr> tmp = auto_ptr<test_ptr> (new test_ptr());
}
system("pause");
return 0;
}

在main函數(shù)中,創(chuàng)建test_ptr類(lèi)型指針時(shí),該指針是auto_ptr 類(lèi)型的智能指針,當(dāng)智能指針失效時(shí),會(huì)自動(dòng)調(diào)用該類(lèi)的析構(gòu)函數(shù)。所以這種寫(xiě)法可以不再顯示調(diào)用delete 語(yǔ)句了。但是該智能指針也只是保證調(diào)用類(lèi)的析構(gòu)函數(shù),如果析構(gòu)函數(shù)并沒(méi)有釋放類(lèi)中聲明的變量,那該怎么辦。

代碼片段四:

?
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
#include <iostream>
#include <string.h>
#include <memory>
#include <string>
#include <Windows.h>
#include <map>
#include <ctime>
#include <vector>
using namespace std;
#define MAXN 20000000
class test_ptr
{
public:
//auto_ptr<map<int,int> > p;
map<int,int> *p;
test_ptr()
{
//p = auto_ptr<map<int,int> > (new map<int,int>());
p = new map<int,int>();
for(int i = 0;i<MAXN;i++)
p->insert(make_pair(i,i));
}
/*
~test_ptr()
{
delete p;
}
*/
};
int main(int argc,char *argv[])
{
for(int i = 0;i<100;i++)
{
Sleep(1000);
cout << i << endl; //輸出創(chuàng)建次數(shù)
auto_ptr<test_ptr> tmp = auto_ptr<test_ptr> (new test_ptr());
}
system("pause");
return 0;
}

在這種情況下,還是會(huì)出現(xiàn)內(nèi)存泄漏問(wèn)題,為了解決該問(wèn)題,對(duì)類(lèi)中聲明的指針也是需要聲明為auto_ptr類(lèi)型。

代碼片段五:

?
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
#include <iostream>
#include <string.h>
#include <memory>
#include <string>
#include <Windows.h>
#include <map>
#include <ctime>
#include <vector>
using namespace std;
#define MAXN 20000000
class test_ptr
{
public:
auto_ptr<map<int,int> > p;
test_ptr()
{
p = auto_ptr<map<int,int> > (new map<int,int>());
for(int i = 0;i<MAXN;i++)
p->insert(make_pair(i,i));
}
};
int main(int argc,char *argv[])
{
for(int i = 0;i<100;i++)
{
Sleep(1000);
cout << i << endl; //輸出創(chuàng)建次數(shù)
auto_ptr<test_ptr> tmp = auto_ptr<test_ptr> (new test_ptr());
}
system("pause");
return 0;
}

這樣就不用顯示定義類(lèi)的析構(gòu)函數(shù),不用在外部顯示調(diào)用delete函數(shù),當(dāng)然如果盡早調(diào)用delete函數(shù)也是可以的,盡早釋放內(nèi)存也比該指針失效再釋放好一些,這些就是為了防止忘記調(diào)用。

通過(guò)如上分析:可以得出如下結(jié)論。

1 定義了智能指針,當(dāng)智能指針失效時(shí)會(huì)自動(dòng)調(diào)用類(lèi)的析構(gòu)函數(shù)。

2 在 類(lèi)中定義的智能指針,不必在析構(gòu)函數(shù)中顯示的delete,當(dāng)外部調(diào)用該類(lèi)的析構(gòu)函數(shù)時(shí),會(huì)自動(dòng)釋放該智能指針指向的對(duì)象,釋放內(nèi)存。

3 如果類(lèi)中定義的是智能指針,但是外部沒(méi)有觸發(fā)類(lèi)中的析構(gòu)函數(shù)調(diào)用,該智能指針指向的對(duì)象還是不能釋放。

auto_ptr 智能指針的bug

auto_ptr 智能指針在c++ 11 標(biāo)準(zhǔn)中已經(jīng)被拋棄,被拋棄的原因就是因?yàn)樵揵ug。前面也提到過(guò),一個(gè)對(duì)象只能被一個(gè)智能指針?biāo)茫@樣就會(huì)導(dǎo)致一個(gè)賦值問(wèn)題。看如下代碼

代碼片段六:

?
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
#include <iostream>
#include <string.h>
#include <memory>
#include <set>
using namespace std;
#define MAXN 20000000
void pri(auto_ptr<set<int> > p)
{
set<int>::iterator ite = p->begin();
for(;ite!=p->end();ite++)
{
cout << *ite << endl;
}
}
int main(int argc,char *argv[])
{
auto_ptr<set<int> > ptr(new set<int> ());
for(int i = 0;i< 3;i++)
{
int a;
cin >> a;
ptr->insert(a);
}
pri(ptr);
pri(ptr);
system("pause");
return 0;
}

初看這代碼沒(méi)什么問(wèn)題,不過(guò)運(yùn)行程序會(huì)崩潰。這就是該智能指針最大的bug, 在程序32行 調(diào)用pri(ptr) ,程序到這并沒(méi)什么問(wèn)題,但是第二次調(diào)用pri(ptr) 時(shí)程序就會(huì)崩潰。原因就是前面講過(guò),一個(gè)對(duì)象智能被一個(gè)智能指針?biāo)赶颍诘谝淮握{(diào)用pri()函數(shù)時(shí),為了保證這一原則,當(dāng)把ptr指針傳入pri函數(shù)時(shí),程序內(nèi)部就把ptr置為空,所以到第二次調(diào)用時(shí),就會(huì)出現(xiàn)崩潰的情況。對(duì)于這種情況的解決之道就是使用shared_ptr 指針(該指針的原理是通過(guò)引用計(jì)數(shù)器來(lái)實(shí)現(xiàn)的)。

如果要使用shared_ptr 智能指針,需要安裝boost庫(kù),該庫(kù)還包括許多其他功能。有興趣的可以嘗試以下,該類(lèi)中的智能指針還是比較好用。也不存在很多其他bug。

以上所述是小編給大家介紹的C++中的auto_ptr智能指針實(shí)例詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!

原文鏈接:http://www.cnblogs.com/ChenAlong/archive/2016/07/12/5662851.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜无码片在线观看影院 | 女上男下gifxxoo动态视频 | 亚洲日韩精品欧美一区二区一 | 免费理伦片在线观看全网站 | 香蕉久久一区二区三区 | 国产精品福利久久2020 | 国产精品猎奇系列在线观看 | 国产精品自在线 | 免费欧美一级 | 亚洲精品午夜级久久久久 | 欧美日韩中文字幕在线视频 | 粉嫩尤物在线456 | 国产精品久久久久久久久久久久久久 | 成人国产精品视频 | 欧美日韩一区二区综合 | 四虎国产精品免费入口 | hd在线观看免费高清视频 | 国产精品视频第一区二区三区 | 大又大又黄又爽免费毛片 | 99热这里只有精品在线观看 | 国产精品欧美在线观看 | 国产日本免费 | 99综合在线 | 日本特级a禁片在线播放 | 亚洲精品久久久992KVTV | 91制片在线观看 | 9久热久爱免费精品视频在线观看 | 亚洲国产情侣一区二区三区 | 亚洲第6页 | 国产精品资源在线观看网站 | 五月天色小说 | 狠狠色婷婷狠狠狠亚洲综合 | 精品99一区二区三区麻豆 | 国产精品色拉拉免费看 | 99精品国产成人一区二区 | 日韩欧美亚洲国产高清在线 | 日韩三及片 | 男人捅女人漫画 | 亚洲一级特黄 | fistingvideos头交尿眼 | 久青草国产97香蕉在线视频 |