zoukankan      html  css  js  c++  java
  • 第九课 智能指针

      智能指针在开发中无处不在,智能指针就是用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;
    }

    编译结果如下:

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

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

    智能指针的使用军规:

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

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

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

    小结:

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

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

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

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

  • 相关阅读:
    css单位及颜色值
    web表单作业
    打卡第一天
    IIS的应用池-网站
    Sublime 提示 The package specified, DocBlockr, is not available
    Git/GitHub 初用体验与总结
    自定义置顶TOP按钮
    Firebug 学习使用教程
    ASP.NET导出文件FileResult的使用
    DataGrid获取当前行某列值
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9497898.html
Copyright © 2011-2022 走看看