使用智能指针需要包含头文件
MSDN对 auto_ptr 的定义为:
The template class describes an object that stores a pointer to anallocated object of type Type * that ensures the object to which itpoints gets deleted when its enclosing auto_ptr gets destroyed.
auto_ptr 对象将会绑定一个指定类型的指针,并且负责该指针资源的释放。auto_ptr 的基本使用方法如下所示:
struct MyStruct
{
MyStruct(){cout<<"MyStruct()\n";}
~MyStruct(){cout<<"~MyStruct()\n";}
int i;
int j;
};
auto_ptr pStruct(new MyStruct);
pStruct->i = 1;
pStruct->j = 2;
(*pStruct).i = 3;
(*pStruct).j = 4;
如上所示
auto_ptr
pStruct->i = 1;
pStruct->j = 2;
-> 操作符用于返回指针。智能指针类还重载了 * 操作符,用于返回对象的引用,例如
(*pStruct).i = 3;
(*pStruct).j = 4;
(*pStruct) 返回的是对象的引用,因此可以使用 (*pStruct).j 来访问该对象的成员。
struct MyStruct
{
MyStruct(){cout<<"MyStruct()\n";}
~MyStruct(){cout<<"~MyStruct()\n";}
int i;
int j;
};
{
//compile OK, but we cannot use auto_ptr this way!
auto_ptr pStructArr(new MyStruct[5]);
}
auto_ptr pInt(new int(3));
auto_ptr pInt2 = pInt;
当需要判断auto_ptr 对象是否绑定一个指针时,使用 get() 函数进行判断
auto_ptr pInt(new int(3));
if( pInt.get() )
cout<< *pInt<< endl;
//error C2451: conditional expression of type 'std::auto_ptr<_Ty>' is illegal
if( pInt )
cout<< *pInt << endl;
get() 用于返回 auto_ptr 管理的指针对象,因此判断是否绑定了指针要使用 obj.get() 的方式,auto_ptr 对象不能直接判断,如上例的 if( pInt ) 所示,编译器提示的错误如注释所示。
如果想要改变auto_ptr 管理的指针,使用 reset 函数,例如:
#include"stdafx.h"
#include
#include
#include
using namespace std;
int main()
{
struct MyStruct
{
MyStruct(int ii) : i(ii) {cout<<"MyStruct() i="<< i << endl;}
~MyStruct(){cout<<"~MyStruct()i="<< i << endl;;}
int i;
};
auto_ptr pMyStruct(new MyStruct(5));
pMyStruct.reset(new MyStruct(10));
system("pause");
return 0;
}
由输出结果可以看出,
pMyStruct.reset(newMyStruct(10));
将auto_ptr对象重新绑定了新的指针。需要注意的,原绑定的资源在auto_ptr重新绑定资源后得到了释放!这就是 auto_ptr 的特性,一旦改变资源,原资源就会被释放。
根据auto_ptr的特点,在使用auto_ptr 时遵循如下的原则:
(1)不要使用auto_ptr 绑定指向静态分配对象的指针。
(2)不要使用两个auto_ptr 对象指向同一个对象。
(3)不要使用auto_ptr 对象保存指向动态分配数组的指针。
(4)不要将auto_ptr 对象存储在容器中,因为它不满足容易对存储对象赋值和复制的条件要求。
建议 auto_ptr 在函数体内动态申请局部变量的指针并且不需要进行指针的复制、赋值时使用。
CSDN 对 shared_ptr 的说明如下:
The template class describes an object that uses reference counting to manage resources. A shared_ptrobject effectively holds a pointer to the resource that it owns or holds a null pointer. A resource can be owned by more than one shared_ptr object; when the last shared_ptr object that owns a particular resource is destroyed, the resource is freed.
由定义可以看出,shared_ptr 使用引用计数的方式来实现对指针资源的管理。同一个指针资源,可以被多个 shared_ptr 对象所拥有,直到最后一个 shared_ptr 对象析构时才释放所管理的对象资源。
可以说,shared_ptr 是最智能的智能指针,因为其特点最接近原始的指针。不仅能够自由的赋值和拷贝,而且可以安全的用在标准容器中。
shared_ptr 和 auto_ptr 一样,也是重载了 -> 和 * 操作符,使用 get() 函数可以得到原始的指针,auto_ptr 提供了隐式的bool类型转换,可以直接用于判断auto_ptr对象是否绑定了指针资源。 use_cout() 用于返回当前资源的引用计数。
#include"stdafx.h"
#include
#include
#include
using namespace std;
int main()
{
struct MyStruct
{
MyStruct(int ii) : i(ii) {cout<<"MyStruct() i="<< i << endl;}
~MyStruct(){cout<<"~MyStruct()i="<< i << endl;;}
int i;
};
{
//spMyStruct 维护一个MyStruct 类型的指针
shared_ptr spMyStruct(new MyStruct(10));
//与 auto_ptr 不同的是 shared_ptr 提供了隐式的bool类型转换,用于判断是否已绑定了资源
if(spMyStruct)
{
cout << "1. Use count = " << spMyStruct.use_count() << endl;
shared_ptr spMyStruct2 = spMyStruct; //赋值
cout<< "2. Use count = " << spMyStruct2.use_count() << endl;
shared_ptr spMyStruct3(spMyStruct2); //拷贝
cout<< "3. Use count = " << spMyStruct3.use_count() << endl;
spMyStruct2.reset();
cout<< "4. After reset, use count = " << spMyStruct.use_count() << endl;
}
cout << "5. spMyStruct2 and spMystruct3 out of scope:" << endl;
cout << "6. use count = " << spMyStruct.use_count() << endl;
cout <<"7. spMyStruct out of scope:" << endl;
}
system("pause");
return 0;
}
由输出结果可以看出,对auto_ptr进行复制或者拷贝,实质是增添了引用计数, 和 auto_ptr 不同的是, reset() 函数在 shared_ptr 中的作用是对引用计数减1,并不会立即释放资源。知道引用计数减为0时,资源才得到真正的释放。
use_count()在实际的应用中很少使用,一般是用于调试,shared_ptr提供了一个高效的函数 unique(),同
use_count==1
等效,即,当维护的指针资源引用计数为1时,返回true.
shared_ptr 的类型转换不能使用一般的static_cast,这种方式进行的转换会导致转换后的指针无法再被shared_ptr对象正确的管理。应该使用专门用于shared_ptr类型转换的 static_pointer_cast
#include"stdafx.h"
#include
#include
#include
using namespace std;
class BaseClass
{
public:
BaseClass(){}
~BaseClass(){}
public:
virtual void Func() { cout<<"BaseClass::Func()\n";}
};
class DeriveClass : public BaseClass
{
public:
DeriveClass(){}
~DeriveClass(){}
public:
virtual void Func() override { cout << "DeriveClass::Func()\n";}
};
int main()
{
shared_ptr spBase( new BaseClass() );
spBase->Func(); // 输出 BaseClass::Func()
shared_ptr spDerive( new DeriveClass() );
spDerive->Func();// 输出 DeriveClass::Func()
shared_ptr spBase2 = dynamic_pointer_cast(spDerive);
spBase2->Func();// 输出 DeriveClass::Func()
system("pause");
return 0;
}
使用shared_ptr 避免了手动使用delete来释放由new 申请的资源,标准库也引入了make_shared函数来创建一个shared_ptr对象,使用shared_ptr 和 make_shared ,你的代码里就可以使 new 和 delete 消失,同时又不必担心内存的泄露。例如:
shared_ptr spInt = make_shared(10);
shared_ptr 是最为智能的智能指针,使用shared_ptr 和 make_shared,可以使你的C++代码几乎永远的和new, delete说再见! shared_ptr可以用在各种场合,局部变量,类的成员变量,参数,容器的元素!你不必担心资源的释放,不必担心内存的泄露!学会并熟练使用shared_ptr,提高开发效率吧。