第九课 智能指针

  智能指针在开发中无处不在,智能指针就是用C++模板技术实现的一个类。

智能指针历史:为了解决内存泄漏

使用智能指针:

智能指针的设计方案:

通过类模板描述指针的行为

  能够定义不同类型的指针对象

重载指针特征操作符(->和*)

  利用对象模拟原生指针的行为

对象在生命周期结束的时候会调用析构函数,然后在析构函数中主动的释放堆空间

 C++原生语言里面不存在智能指针,我们需要自己创建智能指针。

下面我们开始正式的编写可复用库的程序,开发环境为Qt creator,首先给出智能指针的程序如下:

 1 #ifndef SMARTPOINTER_H
 2 #define SMARTPOINTER_H
 3 
 4 namespace DTLib
 5 {
 6 
 7 template <typename T>
 8 class SmartPointer
 9 {
10 protected:
11     T *m_pointer;
12 
13 public:
14     SmartPointer(T *p = NULL)
15     {
16         m_pointer = p;
17     }
18 
19     SmartPointer(const SmartPointer<T>& obj)
20     {
21         m_pointer = obj.m_pointer;
22 
23         const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
24     }
25 
26     SmartPointer<T>& operator= (const SmartPointer<T>& obj)
27     {
28         if(this != &obj)
29         {
30             delete m_pointer;
31 
32             m_pointer = obj.m_pointer;
33 
34             const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
35         }
36 
37         return *this;
38     }
39 
40     T* operator-> ()
41     {
42         return m_pointer;
43     }
44 
45     T& operator* ()
46     {
47         return *m_pointer;
48     }
49 
50     bool isNull()
51     {
52         return (m_pointer == NULL);
53     }
54 
55     T* get()
56     {
57         return m_pointer;
58     }
59 
60     ~SmartPointer()
61     {
62         delete m_pointer;
63     }
64 };
65 
66 }
67 
68 #endif // SMARTPOINTER_H

测试程序的主函数如下:

 1 #include <iostream>
 2 #include <SmartPointer.h>
 3 using namespace std;
 4 using namespace DTLib;
 5 
 6 class Test
 7 {
 8 public:
 9     Test()
10     {
11         cout << "Test()" << endl;
12     }
13 
14     ~Test()
15     {
16         cout << "~Test()" << endl;
17     }
18 };
19 
20 int main()
21 {
22     SmartPointer<Test> sp = new Test();
23     return 0;
24 }

执行结果如下:

可见,我们定义了一个智能指针变量,程序执行时自动执行了构造函数,结束时触发了析构函数。

更改主函数,再次测试:

 1 #include <iostream>
 2 #include <SmartPointer.h>
 3 using namespace std;
 4 using namespace DTLib;
 5 
 6 class Test
 7 {
 8 public:
 9     Test()
10     {
11         cout << "Test()" << endl;
12     }
13 
14     ~Test()
15     {
16         cout << "~Test()" << endl;
17     }
18 };
19 
20 int main()
21 {
22     SmartPointer<Test> sp = new Test();
23 
24     SmartPointer<Test> nsp;
25 
26     nsp = sp;
27 
28     cout << sp.isNull() << endl;
29     cout << nsp.isNull() << endl;
30 
31     return 0;
32 }

结果如下:

可以看到,一片空间只能有一个指针标识。

再次更改主函数测试程序:

int main()
{
    SmartPointer<Test> sp = new Test();

    SmartPointer<Test> nsp;

    nsp = sp;

    nsp++;

    cout << sp.isNull() << endl;
    cout << nsp.isNull() << endl;

    return 0;
}

编译结果如下:

可见,指针不能进行运算。

从以上测试程序得到的结果可以看出,我们的智能指针满足了前文提到的三条要求。

智能指针的使用军规:

  只能用来指向堆空间中的单个对象或者变量。

  不能用来指向堆空间中的数组。

  不能指向局部的对象或者局部变量。

小结:

  指针特征操作符(->和*)可以被重载

  重载指针特征符能够使用对象代替指针

  智能指针只能用于指向堆空间中的内存

  智能指针的意义在于最大程度的避免内存问题

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9497898.html