什麼是智能指針
是C++的一個類模板,用對象去管理指針,想一想之前在使用指正的過程中,經常會出現內存泄漏和內存多次釋放的問題,而智能指針使我們在項目開發中代替了C語言中原生的指針,保證開發更安全,更高效。例如 boost庫的智能指針
爲什麼要使用智能指針
智能指針就是用來管理一個指針,在使用指針的過程中我們都遇到過,指針導致的內存泄漏和內存的多次釋放,而智能指針可以很大程度上避免這些問題,它本身就是一個類,而類的特性就是在執行完時,超出了類的作用域,會自動調用析構函數自動釋放資源。也就是說智能指針會在函數結束時自動釋放內存空間,避免了手動釋放內存帶來的弊端。
智能指針有兩種分類:(這個後面再詳細分析)
1.不帶引用計數的智能指針
2.帶引用計數的智能指針
指針的思想
工程中的智能指針是一個類模板
通過構造函數接管申請的內存
通過析構函數確保堆內存被及時釋放
通過重載指針運算符 * 和 ->來模擬指針的行爲
通過重載比較運算符 == 和 != 來模擬指針的比較。
簡單實現智能指針類
#include <iostream>
using namespace std;
#pragma warning(disable : 4996)
class Test
{
public:
Test(int a)
{
this->m_a = a;
}
void PrintVal()
{
cout << "a = " << m_a << endl;
}
private:
int m_a;
};
class MyTestPointer
{
public:
MyTestPointer()
{
this->p = NULL;
cout << "無參構造函數" << endl;
}
MyTestPointer(Test *p)
{
this->p = p;
cout << "有參構造函數" << endl;
}
~MyTestPointer()
{
delete p;
cout << "析構函數" << endl;
}
Test* operator->()
{
return p;
}
Test &operator*()
{
return *p;
}
private:
Test *p;
};
void PlayObj()
{
Test *p = new Test(10);
p->PrintVal();
delete p;
MyTestPointer t = new Test(20);
t->PrintVal();
}
int main()
{
PlayObj();
system("pause");
return 0;
}
執行結果:
簡單分析一下,我們主要了解一下智能指針的思想。
//1
Test *p = new Test(10);
p->PrintVal();
delete p;
//2
MyTestPointer t = new Test(20);
t->PrintVal();
1)是指針的一般用法,先使用指針申請一個類對象的堆內存,使用完之後我們必須手動delete釋放掉這個內存空間,確保內存泄漏。2)是智能指針的現實用法,不用去考慮內存問題,放心大膽的申請堆內存,當執行完成時,類會自動回收內存空間。是不是更方便和安全了。這就是智能指針的思想。
瞭解過泛型編程之後可以動手實現一個簡易的智能指針類模板。期待!!!
上面是一個指向類類型的指針,下面試着做一個指向int類型的指針。
#include <iostream>
using namespace std;
#pragma warning(disable : 4996)
class Test
{
public:
Test(int a)
{
this->m_a = a;
}
void PrintVal()
{
cout << "a = " << m_a << endl;
}
private:
int m_a;
};
class MyIntPointer
{
public:
MyIntPointer()
{
this->p = NULL;
cout << "無參構造函數" << endl;
}
MyIntPointer(int *p)
{
this->p = p;
cout << "有參構造函數" << endl;
}
~MyIntPointer()
{
delete p;
cout << "析構函數" << endl;
}
int *operator->()
{
return p;
}
int &operator*()
{
return *p;
}
private:
int *p;
};
void PlayObj()
{
int *p = new int(10);
cout << "a = " << *p << endl;
delete p;
MyIntPointert = new int(20);
cout << "a = " << *t << endl;
}
int main()
{
PlayObj();
system("pause");
return 0;
}
執行結果: