auto_ptr和shared_ptr都是智能指针的一种实现,所谓智能指针,多数情况下都是指这样的一些对象:
1. 内部有一个动态分配对象的指针,拥有该对象的使用权和所有权(独占或共享)。
2. 重载*和->操作,行为上跟所拥有的对象的指针一致。
3. 当自身的生命期结束的时候,会做一些跟拥有对象相关的清理动作。
1. auto_ptr
auto_ptr是现在标准库里面一个轻量级的智能指针的实现,存在于头文件 memory中,之所以说它是轻量级,是因为它只有一个成员变量(拥有对象的指针),相关的调用开销也非常小。
/* 关于auto_ptr的几个注意事项:
* 1、auto_ptr不能共享所有权。
* 2、auto_ptr不能指向数组。
* 3、auto_ptr不能作为容器的成员。
* 4、不能通过赋值操作来初始化auto_ptr
* std::auto_ptr<int> p(new int(42)); //OK
* std::auto_ptr<int> p = new int(42); //ERROR
* 这是因为auto_ptr 的构造函数被定义为了explicit
*/
/* 辅助函数:
* 1) get,用来显式的返回auto_ptr所拥有的对象指针。
* 我们可以发现,标准库提供的auto_ptr既不提供从“裸”指针到auto_ptr的隐式转换(构造函数为explicit),
* 也不提供从auto_ptr到“裸”指针的隐式转换,从使用上来讲可能不那么的灵活,考虑到其所带来的安全性还是值得的。
* 2) release,用来转移所有权。
* 3) reset,用来接收所有权,如果接收所有权的auto_ptr如果已经拥有某对象,必须先释放该对象。
*/
#include <memory>
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass(int s):i(s){}
~MyClass() {cout<<"This class has been destroyed. "<<i<<endl;}
void myFunc() {cout<<"myFunc() done. "<<i <<endl;}
private:
int i;
};
int main() {
auto_ptr<MyClass> ptr1(new MyClass(1));
auto_ptr<MyClass> ptr2(new MyClass(2));
ptr1->myFunc();
ptr2->myFunc();
cout<<"test 1 done"<<endl<<endl;
ptr2 = ptr1;
//Here: "ptr2" points to the old "ptr1", and "ptr1" is NULL.
ptr2->myFunc();
cout<<"test 2 done"<<endl<<endl;
MyClass* ptr = ptr2.get();
ptr->myFunc();
ptr2.reset(new MyClass(3));
ptr2->myFunc();
ptr->myFunc(); //Here: the address which "ptr" points to, has been destroyed.
cout<<"test 3 done"<<endl<<endl;
system("pause");
return 0;
}
/*
Output:
myFunc() done. 1
myFunc() done. 2
test 1 done
This class has been destroyed. 2
myFunc() done. 1
test 2 done
myFunc() done. 1
This class has been destroyed. 1
myFunc() done. 3
myFunc() done. -17891602
test 3 done
请按任意键继续. . .
*/
2. shared_ptr
shared_ptr是Boost库所提供的一个智能指针的实现,是为了解决auto_ptr在对象所有权上的局限性(auto_ptr是独占的),在使用引用计数的机制上提供了可以共享所有权的智能指针。
/* shared_ptr: 它是一种引用计数型智能指针,它的复制行为相比auto_ptr要正常许多,它也可以被自由用于STL容器中。
* 但是shared_ptr类不属于标准C++库,而是属于boost的tr1库。
* shared_ptr的用法和auto_ptr类似。
*/
#include <tr1/memory.hpp>
#include <iostream>
#include<vector>
using namespace std;
using std::tr1::shared_ptr;
class MyClass {
public:
MyClass(int s): i(s){}
~MyClass() {cout<<"This class has been destroyed. "<< i <<endl;}
void myFunc() {cout<<"myFunc() done. "<< i <<endl;}
private:
int i;
};
int main() {
//下面分别建立两个智能指针,然后测试他们的基本使用
//注意不能使用如下形式: shared_ptr<MyClass> ptr = new MyClass(2);
shared_ptr<MyClass> ptr1(new MyClass(1));
shared_ptr<MyClass> ptr2(new MyClass(2));
(*ptr1).myFunc();
ptr2->myFunc();
cout<<"test 1 done!"<<endl<<endl;
ptr2 = ptr1;
//Here: "ptr2" and "ptr1" all point to the "old ptr1".
ptr2->myFunc();
ptr1->myFunc();
ptr1.reset();
//Here: the destructor of "old ptr1" is not called.
cout<<"ptr1.reset() done!"<<endl;
ptr2.reset();
//Here: the destructor of "old ptr1" is called!
cout<<"test 2 done!"<<endl<<endl;
MyClass* temp_ptr=new MyClass(3);
ptr1.reset(temp_ptr);//把普通指针委托给智能指针进行托管
delete temp_ptr;
ptr1->myFunc();
cout<<"test 3 done"<<endl<<endl;
//智能指针也可以放入STL容器中,并且不影响其使用
vector<shared_ptr<MyClass>> myVector;
{
shared_ptr<MyClass> temp_shared_ptr(new MyClass(4));
myVector.push_back(temp_shared_ptr);
}//离开temp_shared_ptr的作用域,只是它自己析构,MyClass并不会析构
vector<shared_ptr<MyClass>>::iterator itor =myVector.begin();
(*itor)->myFunc();
myVector.clear();
cout<<"test 4 done!"<<endl<<endl;
system("pause");
return 0;
}
/*
Output:
myFunc() done. 1
myFunc() done. 2
test 1 done!
This class has been destroyed. 2
myFunc() done. 1
myFunc() done. 1
ptr1.reset() done!
This class has been destroyed. 1
test 2 done!
This class has been destroyed. 3
myFunc() done. -17891602
test 3 done
myFunc() done. 4
This class has been destroyed. 4
test 4 done!
请按任意键继续. . .
*/
/* 从运行结果中也可以看出shared_ptr 具有很好的资源管理的能力,可以实现理想的复制操作,并且可以和STL容器兼容。
* 在多线程情况下shared_ptr可以达到和c++内置类型同等的安全性。无疑shared_ptr类将是tr1中最常使用的类型。
*/