C++——几种简单的智能指针

最简单的智能指针就是将指针封装在类里,同时将该类的复制与赋值禁用,也就是使该类失去值语义。

实现代码如下:

 1 #ifndef SMART_PTR_H
 2 #define SMART_PTR_H
 3 #include <iostream>
 4
 5
 6 template <typename T>
 7 class SmartPtr
 8 {
 9 public:
10     typedef T          value_type;
11     typedef T*        pointer;
12     typedef T&        reference;
13
14     SmartPtr(T *ptr = NULL)
15         :_ptr(ptr)
16     { }
17
18     ~SmartPtr() { delete _ptr; }
19
20     reference operator* () const throw()
21     { return *_ptr; }
22
23     pointer operator-> () const throw()
24     { return _ptr; }
25
26 private:
27     SmartPtr(const SmartPtr &);
28     void operator=(const SmartPtr &);
29
30     pointer _ptr;
31 };
32
33 #endif  /*SMART_PTR_H*/

相对于这种最简单的智能指针,我们还可以实现一种具有复制与赋值功能的智能指针——auto_ptr。

实现代码如下:

 1 #ifndef AUTO_PTR_H
 2 #define AUTO_PTR_H
 3 #include <iostream>
 4
 5 template <typename T>
 6 class AutoPtr
 7 {
 8 public:
 9     typedef T     value_type;
10     typedef T*    pointer;
11     typedef T&    reference;
12
13
14     AutoPtr(T *ptr = NULL);
15     AutoPtr(AutoPtr &other);
16     ~AutoPtr();
17     AutoPtr &operator= (AutoPtr &other) throw();
18
19     reference operator*() const throw()
20     { return *_ptr; }
21
22     pointer operator->() const throw()
23     { return _ptr; }
24
25     void reset(T *ptr = NULL) throw()
26     {
27         if(_ptr != ptr)
28         {
29             delete _ptr;
30             _ptr = ptr;
31         }
32     }
33
34     pointer release() throw()
35     {
36         pointer tmp(_ptr);
37         _ptr = NULL;
38         return tmp;
39     }
40
41     operator bool() throw() { return _ptr != NULL; }
42
43 private:
44     value_type *_ptr;
45 };
46
47
48 template <typename T>
49 AutoPtr<T>::AutoPtr(T *ptr)
50     :_ptr(ptr)
51 {
52
53 }
54
55 template <typename T>
56 AutoPtr<T>::AutoPtr(AutoPtr<T> &other)
57     :_ptr(other._ptr)
58 {
59     other._ptr = NULL;
60 }
61
62 template <typename T>
63 AutoPtr<T>::~AutoPtr()
64 {
65     delete _ptr;
66 }
67
68 template <typename T>
69 AutoPtr<T> &AutoPtr<T>::operator= (AutoPtr<T> &other) throw()
70 {
71     reset(other.release());
72
73     return *this;
74 }
75 #endif  /*AUTO_PTR_H*/

在使用AutoPtr时,我们需要注意:

  1.AutoPtr的复制与赋值会引发控制权的转移,这是一种转移语义。

  2.不要使用AutoPtr,尤其是与容器结合。

  3.在AutoPtr中,我们提供了一种转化,将该类可转化为bool型。

对于智能指针来说,比较常用的一种实现方法是使用引用计数,创建新的对象时,我们将计数器count初始化为1,每次复制该对象或将该对象赋值给其他对象时,计数器count加1,析构的时候将计数器减1,当计数器为0时,我们才真正删除该对象内的指针。

具体实现代码如下:

 1 #ifndef COUNT_PTR_H
 2 #define COUNT_PTR_H
 3 #include <iostream>
 4
 5
 6 template <typename T>
 7 class CountPtr
 8 {
 9 public:
10     typedef T                 value_type;
11     typedef T*                pointer;
12     typedef T&                reference;
13
14
15     explicit CountPtr(T *p = NULL);
16     CountPtr(const CountPtr<T> &other);
17     ~CountPtr();
18
19     CountPtr<T> &operator= (const CountPtr<T> &other);
20     reference operator*() const throw() { return *_ptr; }
21
22     pointer operator->() const throw() { return _ptr; }
23
24     size_t count() const throw() { return *_count; }
25
26     void swap(CountPtr<T> &other) throw()
27     {
28         std::swap(_ptr, other._ptr);
29         std::swap(_count, other._count);
30     }
31
32     void reset(T *ptr = NULL) throw()
33     {
34         dispose();
35
36         _ptr = ptr;
37         _count = new size_t(1);
38     }
39
40
41     pointer get() const throw() { return _ptr; }
42
43     bool unique() const throw() { return *_count == 1; }
44
45     operator bool() { return _ptr != NULL; }
46 private:
47
48     void dispose()
49     {
50         if(-- *_count == 0)
51         {
52             delete _ptr;
53             delete _count;
54         }
55     }
56
57     T *_ptr;
58     size_t *_count;
59
60 };
61
62 template <typename T>
63 CountPtr<T>::CountPtr(T *p)
64     :_ptr(p),
65      _count(new size_t(1))
66 {
67
68 }
69
70 template <typename T>
71 CountPtr<T>::~CountPtr()
72 {
73     dispose();
74 }
75
76 template <typename T>
77 CountPtr<T>::CountPtr(const CountPtr<T> &other)
78     :_ptr(other._ptr),
79      _count(other._count)
80 {
81     ++ (*_count);
82 }
83
84 template <typename T>
85 CountPtr<T> &CountPtr<T>::operator= (const CountPtr<T> &other)
86 {
87     ++(*other._count);            //先++防止自身赋值失败
88
89     dispose();
90
91     _ptr = other._ptr;
92     _count = other._count;
93
94     return *this;
95 }
96 #endif  /*COUNT_PTR_H*/

在引用计数智能指针中,需要注意:
  1.计数器count采用指针,这样每个指针共享一个计数。

  2.析构时,仅将引用计数减1,只有当计数为0时,才释放资源。

  3.复制指针时,计数将加1.

  4.赋值时,可以先对other的计数加1,来避免处理自我赋值。

使用引用计数指针,可以将失去值语义的对象放入容器中。

时间: 2025-01-06 04:22:05

C++——几种简单的智能指针的相关文章

简单剖析智能指针的思想

谈到智能指针之前,必须要知道堆栈的相关思想,堆栈在程序开发过程中经常使用到的.比如应用程序的函数当中通过new一个对象,这个对象的实际存储地方是在堆上,而它的指针是保存在栈,在函数执行完毕之后,该对象的指针会被自动从栈中弹出,而其指向的对象会在不会被自动释放,需要通过delete函数来释放该指针所指向的堆栈内存.在开发过程中往往因为忘记delete而造成内存泄露的情况.由此就有智能指针的出现. 智能指针主要思想是:在栈中new一个智能指针对象,而这个智能指针对象指向的实际内容是放在堆上的,在函数

C++智能指针,指针容器原理及简单实现(auto_ptr,scoped_ptr,ptr_vector).

目录 C++智能指针,指针容器原理及简单实现(auto_ptr,scoped_ptr,ptr_vector). auto_ptr scoped_ptr ptr_vector C++智能指针,指针容器原理及简单实现(auto_ptr,scoped_ptr,ptr_vector). 前言 最近再写一个muduo的异步日志接触了很多智能指针,但是又不打算用boost库,只好模一个来用用了. 智能指针的本质即用栈上对象来管理堆上数据的生命周期. 智能指针本身是一个对象,它在栈上创建,构造的时候分配堆上资

浅谈智能指针的历史包袱

我们学习C++的时候,想必都会听说一个叫智能指针的东西,在初听这个词的时候,我们都难免不被“智能”两个字所吸引,感觉它会比较高级,让人有种忍不住想用一把的冲动. 但事实上,它可能并没有我们所想的那样“智能”.好用,它本质上其实就是一个对象,它去接管了原指针所管理的资源.但这里单单用一个对象就想有“智能”的效果并没有那么容易.在智能指针发展的过程中,出现了Autor_ptr等多种版本的智能指针,但它们都确都或多或少有一些问题存在(相信早期的前辈们会深有感触).但智能指针的使用性却是不可否认的.它在

智能指针简单实现

很多人都误以为智能指针是一个指针,其实不然,智能指针不是指针,智能指针是一个模板,由智能指针实例化出来的的对象具有和常规指针相似的行为,但是他能够自动的释放所指向的对象,所以我们称之为智能指针.如果我们用普通指针来创建一个指向某个对象的指针,那么我们最后必须要手动释放这块空间,而智能指针它是一个类,它释放空间是通过析构函数完成的,正是由于有了这一层封装机制,所以智能指针才能够管理一个对象的生命周期.(定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可

简单的单例类和智能指针

1.一个简单的单例类: class Singleton { public: static Singleton *getInstance() { if(pInstance_ == NULL){ mutex_.lock(); if(pInstance_ == NULL){ sleep(1); pInstance_ = new Singleton; } mutex_.unlock(); } return pInstance_; } private: Singleton(){} static Singl

C++智能指针剖析(下)boost::shared_ptr&amp;其他

1. boost::shared_ptr 前面我已经讲解了两个比较简单的智能指针,它们都有各自的优缺点.由于 boost::scoped_ptr 独享所有权,当我们真真需要复制智能指针时,需求便满足不了了,如此我们再引入一个智能指针,专门用于处理复制,参数传递的情况,这便是如下的boost::shared_ptr. boost::shared_ptr 属于 boost 库,定义在 namespace boost 中,包含头文件#include<boost/smart_ptr.hpp> 便可以使

智能指针auto_ptr详解

概述:C++中有很多种智能指针,auto_ptr就是其中的一种,该智能指针主要是为了解决"因程序异常退出发生的内存泄漏"这类问题的. 我们先来看下面的问题代码 #include<iostream> #include<memory> #include<exception> using namespace std; //一般指针的处理方式 template<typename T> class OldClass { public: OldCla

Boost智能指针-基础篇

简介 内存管理一直是 C++ 一个比较繁琐的问题,而智能指针却可以很好的解决这个问题,在初始化时就已经预定了删除,排解了后顾之忧.1998年修订的第一版C++标准只提供了一种智能指针:std::auto_ptr(现以废弃),它基本上就像是个普通的指针:通过地址来访问一个动态分配的对象.std::auto_ptr之所以被看作是智能指针,是因为它会在析构的时候调用delete操作符来自动释放所包含的对象.当然这要求在初始化的时候,传给它一个由new操作符返回的对象的地址.既然std::auto_pt

cocos2d智能指针 转自:http://blog.csdn.net/nxshow/article/details/44699409

智能指针在C++11的标准中已经存在了, 分别是unique_ptr,shared_ptr,weak_ptr, 其中最常用的应该是share_ptr, 它采用引用计数的方式管理内存, 当引用计数为0的时候, 自动释放内存, 但是由于shared_ptr考虑到了线程安全, 所以会存在有较大的性能损失. 所以在实时游戏开发中, 往往不会用到shared_ptr. 在cocos2d-x3.2以及更高的版本中, cocos2d-x提供了自己的智能指针方案——RefPtr, 这套方案实际上也是模仿C++1