在C++中,当我们用new为一个指针开辟一段内存后,在用完指针后,我们需要用delete把开辟的空间释放掉,但是当程序足够大时,指针会很多,我们可能会遗漏一部分指针。这个时候,如果我们采用智能指针,那就非常好了。
在std命名空间中,我们有auto_ptr(C++ 11 中已经没有了)、unique_ptr、shared_ptr、weak_ptr;在boost命名空间中,有shared_ptr、scoped_ptr、intrusive_ptr、weak_ptr、shared_array、scoped_array。
1.unique_ptr的使用方法
判断指针是否为空,用unique_ptr.get();
std::unique_ptr<int> unique_1(new int); ///定义了一个unique_ptr的int智能指针
*unique_1 = 10; //// 给指针赋值为10
*unique_1 = 20; //可以修改指针指向的值
std::unique_ptr<int> unique_2 =std::move(unique_1); ///使用move函数将unique_1 释放,同时将地址转移给unique_2,之后unique_1为空,*unique_2 为20
std::unique_ptr<int []> ArrrayP(new int[5]) ; ///定义了一个数组类型的智能指针
int arr[5] = {2,3,4,5,6};
ArrrayP[0] = 2;
ArrrayP[4] = 3;/////没有对1,2,3赋值,所以输出结果不正确
for (int i =0 ;i < 5; i++)
{
printf("%d ",ArrrayP[i] );
}
2.shared_ptr的使用方法
int a = 10;
std::shared_ptr<int> pas(new int); //定义了一个int型的shared_ptr智能指针,此时pas已经有地址了
*pas = 20; //故可以直接对其赋值,若上述为std::shared_ptr<int> pas;则pas为空,是不可以进行赋值的
pas = std::make_shared<int>(a); ///此时将a绑定到shared_ptr的pas上,pas的地址将与上一行的不同;
std::shared_ptr<string> p(new string);
*p = "dsfsfyhnfghfhgfhdsfdds" ;
*p = "sdfs"; ///可以修改值
std::vector<int> vData(2,5);// 5 5
std::shared_ptr<std::vector<int> > pvData;
pvData = std::make_shared<std::vector<int> > (vData);
std::shared_ptr<std::vector<int> > pvDataA(pvData);
pvData->push_back(20); ///5 5 20
pvData->pop_back(); /// 5 5
pvDataA->push_back(3);/// 5 5 3
pvDataA.reset();////pvDataA为空,pvData中仍然为5 5 3
auto ResA = pvDataA.get(); ///ResA 为 0 ,pvDataA现在为空
pvData.reset(); ////pvDataA为空,pvData也为空
auto Res = pvData.get();
int dataA = 1;
int *pD = &dataA ;
std::shared_ptr<int> pData = std::make_shared<int>(dataA);
std::shared_ptr<int> pDataA(pData);
dataA = *pData + dataA;
printf("%d
" ,dataA); //// 2
printf("%d
" ,*pData);//// 1
printf("%d
" ,*pD);///// 2
经过看内存地址发现,pData与&dataA的地址是不一样吧的,所以在修改dataA时,*pData的值并没有发生变化。
2.weak_ptr的使用方法
weak_ptr是没有重载*和->运算的,所以它没有一般指针的功能,它配合shared_ptr来使用,保证其在发生循环引用时,最后析构不会发生对同一内存的多次析构或永远不会释放掉内存,有use_count()函数,可以查看shared_ptr一共共享了几次。