auto_ptr & shared_ptr

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中最常使用的类型。
*/

你可能感兴趣的:(shared_ptr,auto_ptr)