2017年计算机二级C++实例编程:一个简单的智能指针实现

来源:学生作业帮助网 编辑:作业帮 时间:2024/11/27 07:20:27 计算机等级考试
2017年计算机二级C++实例编程:一个简单的智能指针实现
2017年计算机二级C++实例编程:一个简单的智能指针实现计算机等级考试

  一个简单的智能指针实现

  学习这个代码有助于理解shared_ptr指针的实现方法

  smart.cpp

  1 namespace smart

  2 {

  3 // 引用计数类.

  4 class smart_count

  5 {

  6 public:

  7 smart_count(int c = 0) : use_count(c) {}

  8 ~smart_count() {}

  9

  10 // 增加引用计数, 并返回计数值.

  11 int addref() { return ++use_count; }

  12 // 减少引用计数, 并返回计数值.

  13 int release() { return --use_count; }

  14

  15 private:

  16 // 计数变量.

  17 int use_count;

  18 };

  19

  20 // 智能指针.

  21 template

  22 class smart_ptr

  23 {

  24 public:

  25 // 构造指针, 并使引用计数置为1.

  26 explicit smart_ptr (T* ptr) : p(ptr), u(new smart_count(1))

  27 {}

  28

  29 // 构造空指针.

  30 explicit smart_ptr () : p(NULL), u(NULL)

  31 {}

  32

  33 // 智能指针析构.

  34 ~smart_ptr (void)

  35 {

  36 // 如果引用计数等于0, 则删除数据和引用计数, 并置p为NULL.

  37 // 此处需要注意的是, 共用的u并未置为 NULL, 在其它指针析构

  38 // 时, p为NULL, 则不会重复delete.

  39 if (p && u->release() <= 0)

  40 {

  41 delete p;

  42 delete u;

  43 p = NULL;

  44 }

  45 }

  46

  47 // 智能指针拷贝构造函数.

  48 smart_ptr (const smart_ptr& t)

  49 {

  50 p = t.p;

  51 u = t.u;

  52

  53 if (u) // 必须判断空值.

  54 {

  55 u->addref(); // 增加引用计数.

  56 }

  57 }

  58

  59 // 指针赋值.

  60 void operator= (smart_ptr& t)

  61 {

  62 // 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.

  63 if (p && u->release() <= 0)

  64 {

  65 delete p;

  66 delete u;

  67 }

  68

  69 // 直接赋值.

  70 p = t.p;

  71 u = t.u;

  72

  73 if (u) // 必须判断空值.

  74 {

  75 u->addref(); // 增加引用计数.

  76 }

  77 }

  78

  79 // 重载->操作和*操作符.

  80 T *operator-> (void) { return p; }

  81 T& operator *(void) { return *p; }

  82 // 重载!操作符.

  83 bool operator! () const { return !p;}

  84

  85 // 重载指针bool值操作符.

  86 typedef smart_ptr this_type;

  87 typedef T * this_type::*unspecified_bool_type;

  88 operator unspecified_bool_type() const { return !p ? 0: &this_type::p; }

  89 // 得到原指针.

  90 T* get() { return p; }

  91 void reset(T* ptr)

  92 {

  93 // 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.

  94 if (p && u->release() <= 0)

  95 {

  96 delete p;

  97 delete u;

  98 }

  99

  100 // 赋值, 如果是NULL, 则不创建引用计数.

  101 p = ptr;

  102 if (p)

  103 u = new smart_count(1);

  104 else

  105 u = NULL;

  106 }

  107

  108 void reset(smart_ptr& t)

  109 {

  110 // 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.

  111 if (p && u->release() <= 0)

  112 {

  113 delete p;

  114 delete u;

  115 }

  116

  117 // 赋值.

  118 p = t.p;

  119 u = t.u;

  120

  121 if (u) // 必须判断空值.

  122 {

  123 u->addref(); // 增加引用计数.

  124 }

  125 }

  126

  127 private:

  128 T* p;

  129 smart_count* u;

  130 };

  131

  132 // 重载==操作符.

  133 template inline bool operator==(smart_ptr & a, smart_ptr & b)

  134 {

  135 return a.get() == b.get();

  136 }

  137

  138 // 重载!=操作符.

  139 template inline bool operator!=(smart_ptr & a, smart_ptr & b)

  140 {

  141 return a.get() != b.get();

  142 }

  143 }计算机等级考试