总结:
1).auto_ptr只能作为常量来保护,建议使用boost库的scoped_ptr就足够了,不要使用auto_ptr进行赋值和容器管理。
2).对于需要对智能指针进行赋值\函数传递\容器管理\对象数组指针类型的操作,使用boost的shared_ptr,因为它使用了引用计数,否则使用auto_ptr只能对auto_ptr的引用或地址操作才是安全的。
使用auto_ptr需要注意的:
1.不允许两个智能指针指向同一个对象,否则会导致删除时候删到野指针。
2.不要进行智能指针赋值操作,否则所有权将进行传递,除非确定pAutoA以后不会再需要了。
3.函数间传递无论是函数参数还是返回值,不能使用智能指针,若一定要使用只能用智能指针引用或地址,使用时候注意pThreeAutoA也是有&符号的,传递要非常小心。
4.指向数组,智能指针释放的时候只是delete没有delete[],导致隐性的严重的内存泄露。
5.STL容器管理指针指针不可以,但是管理智能指针的地址是可以的,但是这么做中间改变了智能指针也会悲剧。
测试代码:
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class A
{
public:
void SetNum(int num)
{
m_nNum = num;
}
void Display()
{
cout<<"m_nNum value:"<<m_nNum<<endl;
}
private:
int m_nNum;
};
// 智能指针传递,需要使用常量引用或者常量指针在函数之间传递
const auto_ptr<A>& TransferAutoPtrByReference(const auto_ptr<A> &p)
{
return p;
}
const auto_ptr<A>* TransferAutoPtrByPtr(const auto_ptr<A> *p)
{
return p;
}
int main()
{
A *pObj = new A;
auto_ptr<A> pAutoA(pObj);
//auto_ptr<A> pAutoA2(pObj); // 1.不允许的,两个智能指针指向同一个对象会导致删除时候删到野指针
pAutoA->SetNum(10);
pAutoA->Display();
auto_ptr<A> pSecondAutoA = pAutoA; // 2.不要进行赋值操作,否则所有权将进行传递,除非确定pAutoA以后不会再需要了
/*if(pAutoA._Myptr == NULL) // pAutoA._Myptr变为了空但是是私有成员,pAutoA是野指针
{
pAutoA->SetNum(100);
pAutoA->Display();
}*/
pSecondAutoA->Display();
const auto_ptr<A> &pThreeAutoA = TransferAutoPtrByReference(pSecondAutoA);// 3.使用时候注意pThreeAutoA也是有&符号的,传递要非常小心
pSecondAutoA->Display();
pThreeAutoA->Display();
const auto_ptr<A> *pFourAutoA = TransferAutoPtrByPtr(&pSecondAutoA);// 使用时候注意pFourAutoA是智能指针的地址,传递要非常小心
pSecondAutoA->Display();
(*pFourAutoA)->Display();
A *pArrayA = new A[10];
auto_ptr<A> pArrayAutoPtr(pArrayA);// 4.指向数组,智能指针释放的时候只是delete没有delete[],导致隐性的严重的内存泄露
pArrayAutoPtr->SetNum(1);
pArrayAutoPtr->Display();
vector<auto_ptr<A>*> vecPtrA;// 5.STL容器管理指针指针不可以,但是管理智能指针的地址是可以的,但是这么做中间改变了智能指针也会悲剧
vecPtrA.push_back(&pSecondAutoA);
vector<auto_ptr<A>*>::iterator itrA = vecPtrA.begin();
for(; itrA != vecPtrA.end(); ++itrA)
{
(*(*itrA))->SetNum(999);
(*(*itrA))->Display();
}
}