Smart Pointer 智能指针

P76

参考:http://www.cnblogs.com/lanxuezaipiao/p/4132096.html

  http://blog.csdn.net/hackbuteer1/article/details/7561235

简介

智能指针是存储指向动态分类(堆)对象的指针的类,用于生存期控制,确保在离开指针作用域时,自动正确销毁动态分配的对象。

通过引用计数的技术来实现,每使用它一次,内部的引用计数就加1,每析构一次,引用计数减1,减到0时就销毁对象,回收内存。

头文件 #include <memory>

分类

三种智能指针:

  • std::shared_ptr  实现共享式拥有,多个指针可以指向相同的对象,该对象和相关资源会在最后一个reference被销毁时释放
  • std::unique_ptr  实现独占式拥有,保证同一时间内只有一个指针可以指向该对象
  • std::weak_ptr    持有被shared_ptr所管理对象的引用,但是不会改变引用计数值。允许共享但不拥有某对象

另一方面,auto_ptr已经被废弃,C98,之前和std::unique_ptr一个意思

使用

 1 #include <iostream>
 2 #include <string>
 3 #include <memory>
 4 
 5 class report
 6 {
 7 private:
 8     std::string str;
 9 public:
10  report(const std::string s) : str(s) {
11   std::cout << "Object created.\n";
12  }
13  ~report() {
14   std::cout << "Object deleted.\n";
15  }
16  void comment() const {
17   std::cout << str << "\n";
18  }
19 };
20 
21 int main() {
22  {
23   std::auto_ptr<report> ps(new report("using auto ptr"));
24   ps->comment();
25  }
26 
27  {
28   std::shared_ptr<report> ps(new report("using shared ptr"));
29   ps->comment();
30  }
31 
32  {
33   std::unique_ptr<report> ps(new report("using unique ptr"));
34   ps->comment();
35  }
36  return 0;
37 }

 

注意:智能指针的初始化必须使用复制初始化而不能采用赋值初始化,因为智能指针类的构造函数是explicit,只能够显示的调用构造函数

str_ptr<string> p1 = new string("hello")    //error,赋值初始化隐式调用构造函数

str_ptr<string> p2(new string("world"))    //OK

 

unique_ptr注意拥有权必须用move

    unique_ptr<string> p2(new string("hello"));
    unique_ptr<string> p3;
    p3 = std::move(p2);

p2失去拥有权不能在被调用了

unique_ptr比auto_ptr的好处在于如果p3 = p2,unique_ptr在编译时就能发现错误,auto_ptr要在运行时才能发现错误

shared_ptr实现

参考:http://www.jianshu.com/p/0300b2d833af

分析:

成员,一个模板指针T *p,一个引用计数的int *count;

成员函数:

构造函数:接受T *参数初始化成员p,初始化count为1,注意count需要new,p就不用了,p是在使用过程中new的

复制构造函数:注意形参不要用const类型,是引用类型的smart_point类,让count等于形参.count++,让p等于形参.p

析构函数:首先先对*count自减,不是0就算了,是0的话delete   p和count

然后写重载几个运算符*,->和=

*是返回T&类型,返回*p

->返回T*类型也就是指针,返回的是p

=首先将*count加一,然后为了防止自己=自己要判断count自减后是不是0,最后用对count和p进行赋值操作

 1 #include <string>
 2 #include <iostream>
 3 using namespace std;
 4 
 5 template <typename T>
 6 class smart_ptrs {
 7 
 8 public:
 9     smart_ptrs(T*); //用普通指针初始化智能指针
10     smart_ptrs(smart_ptrs&);
11 
12     T* operator->(); //自定义指针运算符
13     T& operator*(); //自定义解引用运算符
14     smart_ptrs& operator=(smart_ptrs&); //自定义赋值运算符
15 
16     ~smart_ptrs(); //自定义析构函数
17 
18 private:
19     int *count; //引用计数
20     T *p; //智能指针底层保管的指针
21 };
22 
23 template <typename T>
24 smart_ptrs<T>::smart_ptrs(T *p) : count(new int(1)), p(p) {
25     cout << "创建对象" << *p << ",引用计数:" << *count << endl;
26 }
27 
28 template <typename T>
29 //对普通指针进行拷贝,同时引用计数器加1,因为需要对参数进行修改,所以没有将参数声明为const
30 smart_ptrs<T>::smart_ptrs(smart_ptrs &sp) : count(&(++*sp.count)), p(sp.p)  {
31     cout << "调用复制构造函数,拷贝:" << *sp.p << ",引用计数:" << *count << endl;
32 }
33 
34 template <typename T>
35 T* smart_ptrs<T>::operator->() {
36     return p;
37 }
38 
39 template <typename T>
40 T& smart_ptrs<T>::operator*() {
41     return *p;
42 }
43 
44 template <typename T>
45 smart_ptrs<T>& smart_ptrs<T>::operator=(smart_ptrs& sp) {
46     ++*sp.count;
47     if (--*count == 0) { //自我赋值同样能保持正确
48         delete count;
49         delete p;
50     }
51     this->p = sp.p;
52     this->count = sp.count;
53     cout << "赋值操作," << *this->p << "引用计数变为" << *this->count << endl;
54     return *this;
55 }
56 
57 template <typename T>
58 smart_ptrs<T>::~smart_ptrs() {
59     if (--*count == 0) {
60         delete count;
61         delete p;
62     }
63 }
64 
65 int main()
66 {
67     smart_ptrs<string> pstr(new string("abc"));
68     smart_ptrs<string> pstr2(pstr);
69     smart_ptrs<string> pstr3(new string("bcd"));
70     pstr3 = pstr2;
71 
72     system("pause");
73 }

 

posted on 2016-07-22 21:51  已停更  阅读(531)  评论(0编辑  收藏  举报