C++拾遺--智能指針

                        C++拾遺--智能指針

前言

    內存泄露是常見的問題,新標準中的智能指針從根本上解決了這個問題。所謂的智能指針,其智能性體現在:當沒有對象使用某塊動態分配的內存時,那就自動釋放這片內存。

智能指針

下面這段程序可耗盡內存,導致程序崩潰。

#include <iostream>
#include <Windows.h>
using namespace std;

int main()
{
	while (1)
	{
		//每次動態分配80M內存
		double *p = new double[1024 * 1024 * 10];
		Sleep(2000);
	}
	return 0;
}
這就不運行了……

衆所周知,動態分配的內存需要手動釋放,每次分配80M,不用多久內存就會耗盡。


使用智能指針,就不會出現這種情況,如下

#include <iostream>
#include <Windows.h>
#include <memory>
using namespace std;

int main()
{
	while (1)
	{
		//每次分配800M內存
		shared_ptr<double>p(new double[1024 * 1024 * 100]);
		Sleep(2000);
	}
	return 0;
}
運行後,觀察內存使用情況,最多也只是在800M左右。

以上兩例,粗略看出智能指針的安全性,不過這一切都建立在正確使用的前提下。下面來仔細探討下標準庫提供的智能指針的使用方法。


標準庫中主要提供了兩種智能指針:shared_ptr 和 unique_ptr。它們都是模板,主要區別是shared_ptr允許多個指針指向同一個對象,unique_ptr則獨享一片內存。


共享操作

shared_ptr和unique_ptr都支持的操作

  • shared_ptr<T> p, unique_ptr<T> q 創建指向類型T的空智能指針
  • *p,解引用操作,獲取它指向的對象,類型是T
  • p,將p當做條件判斷,若p指向一個對象,則爲true
  • p.get(),返回p指向對象的指針,類型是T*


shared_ptr

shared_ptr的獨享操作

  • make_shared<T>(arg_list); 返回一個shared_ptr,指向一個動態分配的類型爲T的對象,並且使用arg_list初始化對象。
  • shared_ptr<T>p(q); 把shared_ptr q拷貝賦值給p,此操作會增加q中的計數器
  • p = q; p的計數器減少,q的計數器增加
  • p.use_count(); 返回與p共享對象的智能指針數量
  • p.unique(); 若p.use_count()爲1,返回true 

代碼演示

#include <iostream>
#include <Windows.h>
#include <string>
#include <memory>
using namespace std;

int main()
{
	cout << "******shared_ptr演示***by David***" << endl;
	auto sp1 = make_shared<int>(12); 
	auto i1 = sp1.get();
	cout << typeid(i1).name() << endl;    //int *
	cout << "*sp1 = " << *sp1 << endl;
	auto sp2 = make_shared<string>("zhangxiang");
	auto i2 = sp2.get();
	cout << typeid(i2).name() << endl;    //string *
	cout << "*sp2 = " << *sp2 << endl;
	auto i3 = *sp2;
	cout << typeid(i3).name() << endl;    //string
	auto sp3 = make_shared<string>("David");
	cout << "sp2.unique() = " << sp2.unique() << endl;
	cout << "sp2.use_count() = " << sp2.use_count() << endl;
	cout << "sp3.use_count() = " << sp2.use_count() << endl;
	sp2 = sp3;
	cout << "sp2.use_count() = " << sp2.use_count() << endl;
	cout << "sp3.use_count() = " << sp2.use_count() << endl;
	cin.get();
	return 0;
}
運行



unique_ptr

unique_ptr獨享一片內存,所以不支持拷貝和構造(有例外)






本專欄目錄

所有內容的目錄



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章