最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2016年07月12日 12:00:11   作者:2010120422  
這篇文章主要介紹了C++中的auto_ptr智能指針的作用及使用方法詳解的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

智能指針(auto_ptr) 這個名字聽起來很酷是不是?其實auto_ptr 只是C++標準庫提供的一個類模板,它與傳統(tǒng)的new/delete控制內存相比有一定優(yōu)勢,但也有其局限。本文總結的8個問題足以涵蓋auto_ptr的大部分內容。

 auto_ptr是什么?

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

該類型在頭文件memory中,在程序的開通通過 #include<memory> 導入,接下來講解該智能指針的作用和使用。

使用方法:

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

  比如該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> > ());

  當然可以先定義,后賦值,如下所示:

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

作用1:保證一個對象在某個時間只能被一個該種類型的智能指針所指向,就是通常所說的對象所有權。

作用2:對指向的對象自動釋放的作用,詳情看如下代碼。

代碼片段一:

#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;
} 


在某些情況下,可能我們就會寫出上面的代碼來,通過運行會發(fā)現(xiàn)存在內存溢出。對于一些經驗老道的程序員可能會作如下改寫:

代碼片段二:

#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 類中的析構函數(shù)中添加內存釋放代碼,但是在main函數(shù)中,定義的局部指針,當局部指針失效時并不會自動調用析構函數(shù),在這種情況下也會導致內存泄漏問題。當然,如果細心的程序員可以在 test_ptr * tmp = new test_ptr() 后面加上一句 delete tmp ,這樣也能夠釋放內存,不會出現(xiàn)內存泄漏問題。但是在某些情況下,很容易漏寫,為了解決此問題,auto_ptr 就能發(fā)揮作用了。

代碼片段三:

#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類型指針時,該指針是auto_ptr 類型的智能指針,當智能指針失效時,會自動調用該類的析構函數(shù)。所以這種寫法可以不再顯示調用delete 語句了。但是該智能指針也只是保證調用類的析構函數(shù),如果析構函數(shù)并沒有釋放類中聲明的變量,那該怎么辦。

代碼片段四:

#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;
}

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

代碼片段五:

#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;
}

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

通過如上分析:可以得出如下結論。

1 定義了智能指針,當智能指針失效時會自動調用類的析構函數(shù)。

2 在 類中定義的智能指針,不必在析構函數(shù)中顯示的delete,當外部調用該類的析構函數(shù)時,會自動釋放該智能指針指向的對象,釋放內存。

3 如果類中定義的是智能指針,但是外部沒有觸發(fā)類中的析構函數(shù)調用,該智能指針指向的對象還是不能釋放。

auto_ptr 智能指針的bug

auto_ptr 智能指針在c++ 11 標準中已經被拋棄,被拋棄的原因就是因為該bug。前面也提到過,一個對象只能被一個智能指針所引用,這樣就會導致一個賦值問題??慈缦麓a

代碼片段六:

#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;
}

初看這代碼沒什么問題,不過運行程序會崩潰。這就是該智能指針最大的bug, 在程序32行 調用pri(ptr) ,程序到這并沒什么問題,但是第二次調用pri(ptr) 時程序就會崩潰。原因就是前面講過,一個對象智能被一個智能指針所指向,在第一次調用pri()函數(shù)時,為了保證這一原則,當把ptr指針傳入pri函數(shù)時,程序內部就把ptr置為空,所以到第二次調用時,就會出現(xiàn)崩潰的情況。對于這種情況的解決之道就是使用shared_ptr 指針(該指針的原理是通過引用計數(shù)器來實現(xiàn)的)。

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

以上所述是小編給大家介紹的C++中的auto_ptr智能指針實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

相關文章

  • C++異步操作future和aysnc與function和bind

    C++異步操作future和aysnc與function和bind

    這篇文章主要介紹了C++異步操作future和aysnc與function和bind,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • 手把手教你如何優(yōu)化C語言程序

    手把手教你如何優(yōu)化C語言程序

    程序進行優(yōu)化,通常是指優(yōu)化程序代碼或程序執(zhí)行速度。優(yōu)化代碼和優(yōu)化速度實際上是一個予盾的統(tǒng)一,一般是優(yōu)化了代碼的尺寸,就會帶來執(zhí)行時間的增加,如果優(yōu)化了程序的執(zhí)行速度,通常會帶來代碼增加的副作用,很難魚與熊掌兼得,只能在設計時掌握一個平衡點
    2013-07-07
  • C++ ofstream與ifstream詳細用法

    C++ ofstream與ifstream詳細用法

    ofstream是從內存到硬盤,ifstream是從硬盤到內存,其實所謂的流緩沖就是內存空間
    2013-07-07
  • C語言算法練習之數(shù)組元素排序

    C語言算法練習之數(shù)組元素排序

    這篇文章主要為大家介紹了C語言算法練習中數(shù)組元素排序的實現(xiàn)方法,文中的示例代碼講解詳細,對我們學習C語言有一定幫助,需要的可以參考一下
    2022-09-09
  • QT輸入框輸入限制整理(正則表達式限制)

    QT輸入框輸入限制整理(正則表達式限制)

    我們有時需要限制文本框輸入內容的類型,下面這篇文章主要給大家介紹了關于QT輸入框輸入限制的相關資料,文中通過代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-04-04
  • C++?JSON庫?nlohmann::basic_json::accept的用法解析

    C++?JSON庫?nlohmann::basic_json::accept的用法解析

    nlohmann::basic_json::accept 是 Nlohmann JSON 庫中的一個方法,它用于檢查一個字符串是否可以解析為有效的 JSON,這篇文章主要介紹了C++?JSON庫nlohmann::basic_json::accept的用法,需要的朋友可以參考下
    2023-06-06
  • C語言的進制轉換及算法實現(xiàn)教程

    C語言的進制轉換及算法實現(xiàn)教程

    這篇文章主要介紹了C語言的進制轉換及算法實現(xiàn)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • 詳解C++異常處理三個重要組成部分

    詳解C++異常處理三個重要組成部分

    這篇文章主要為大家介紹了C++異常處理的三個重要組成部分示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • C++中使用mutable關鍵字的場景分析

    C++中使用mutable關鍵字的場景分析

    C++中的mutable關鍵字用于修飾類的成員變量,使其在const成員函數(shù)中可以被修改,它主要用于緩存、線程同步和調試等場景,以支持對象的邏輯常量性,在使用mutable時,應確保其修改不會破壞對象的外部表現(xiàn)狀態(tài),本文介紹C++中使用mutable關鍵字的場景分析,感興趣的朋友一起看看吧
    2025-02-02
  • C++類中變量也可以是引用的代碼實例

    C++類中變量也可以是引用的代碼實例

    今天小編就為大家分享一篇關于C++類中變量也可以是引用的代碼實例,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04

最新評論

沙河市| 福鼎市| 翁牛特旗| 体育| 南丰县| 海丰县| 阿合奇县| 富宁县| 屏边| 股票| 泰州市| 秦皇岛市| 鱼台县| 确山县| 泾川县| 科技| 云浮市| 黄陵县| 和静县| 敦煌市| 梁平县| 巴彦县| 舒兰市| 绥芬河市| 曲松县| 句容市| 内江市| 阳西县| 林口县| 石景山区| 宜都市| 谷城县| 嘉黎县| 怀远县| 黔南| 富川| 四川省| 台中市| 桓台县| 宜章县| 黑龙江省|