zoukankan      html  css  js  c++  java
  • 第37课 智能指针分析(指针特征操作符( -> 、 *)重载)

    1. 永恒的话题:内存泄漏

    (1)动态申请堆空间用完后不归还

    (2)C++语言中没有垃圾回收的机制

    (3)指针无法控制所指堆空间生命周期

    【编程实验】内存泄漏   37-1.cpp

    #include <iostream>
    
    #include "IntArray.h"
    
     
    
    using namespace std;
    
     
    
    class Test
    {
    
        int i;
    
    public:
    
        Test(int i)
    
        {
    
            this->i = i;
    
            cout << "Test(int i)" << endl;
    
        }
    
        int value(){return i;}
    
       
    
        ~Test()
    
        {
    
            cout << "~Test()" << endl;
    
        }
    
       
    
    };
    
     
    
    int main()
    {
    
        for(int i = 0; i < 5; i++)
    
        {
    
            Test* p  = new Test(i);
    
           
    
            cout << p->value() << endl;
    
           
    
            //没有delete p造成内存泄漏
    
        }
    
       
    
        return 0;
    
    }

    运行结果:

      

    2. 深度的思考:我们需要什么?

    (1)需要一个特殊的指针指针生命期结束时主动释放堆空间

    (2)一片堆空间最多只能由一个指针来标识

    (3)杜绝指针运算指针比较因为只有一个该类对象的指针能指向堆空间

    3. 解决方案

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

    (2)只能通过类的成员函数重载

    (3)重载函数不能使用参数

    (4)只能定义一个重载函数

    (5)注意:智能指针只能用来指向堆空间中的对象或变量(不能指向栈)

    【编程实验】智能指针   37-2.cpp

    #include <iostream>
    
    #include "IntArray.h"
    
     
    
    using namespace std;
    
     
    
    class Test
    {
    
        int i;
    
    public:
    
        Test(int i)
    
        {
    
            this->i = i;
    
            cout << "Test(int i)" << endl;
    
        }
    
        int value(){return i;}
    
       
    
        ~Test()
    
        {
    
            cout << "~Test()" << endl;
    
        }
    
       
    
    };
    
     
    
    //定义智能指针类
    class Pointer
    {
    
        Test* mp;//用于保存要被管理对象的指针
    
    public:
    
        Pointer(Test* p = NULL)
    
        {
    
            mp = p;
    
        }
    
       
    
        Pointer(const Pointer& obj)
    
        {
    
            mp = obj.mp;
    
           
    
            //当Pointer p2 = p1时,p1所指的堆空间由p2来接管
    
            //即保证每次只能有一个智能指针指向同一堆空间
    
            const_cast<Pointer&>(obj).mp = NULL;
    
        }
    
       
    
        Pointer& operator = (const Pointer& obj)
    
        {
    
            if( this != &obj)
    
            {
    
                delete mp;
    
                mp = obj.mp;
    
                //保证赋值操作时,只能由一个智能指针指向同一堆空间
    
                const_cast<Pointer&>(obj).mp = NULL;
    
            }
    
        }
    
       
    
        //重载->操作符
    
        Test* operator ->() //不能使用参数,所以也就只能定义一个重载函数
    
        {
    
            return mp;
    
        }
    
       
    
        //重载*操作符
    
        Test& operator*()  //不能使用参数,所以也就只能定义一个重载函数
    
        {
    
            return *mp;
    
        }
    
       
    
        bool isNull()
    
        {
    
            return (mp == NULL);
    
        }
    
       
    
        ~Pointer()
    
        {
    
            delete mp;//智能指针被析构时,同时删除其所管理的Test类的对象
    
        }
    
    };
    
     
    
    int main()
    {
    
        Pointer p1 = new Test(5);
    
       
    
        cout << p1->value() << endl;
    
       
    
        Pointer p2 = p1;//p2接管了p1所指的堆空间,保证每次只能由一个智能指针指向堆空间
    
       
    
        cout << p1.isNull() << endl;//p1指向NULL了,不再指向原来的堆空间
    
        cout << p2->value() << endl;//p2接管了p1所指堆空间
    
       
    
        //p2++;不重载++,因为每次只能一个智能指针指向堆空间,这种++操作没意义
    
       
    
        //p2智能指针生命期结束,会自动释放接管的堆空间
    
       
    
        return 0;
    
    }

    运行结果:

    //输出结果:

    //Test(int i)

    //5

    //1

    //5

    //~Test()

    4. 小结

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

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

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

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

  • 相关阅读:
    面试题 08.02. 迷路的机器人(C++)
    URI和URL的区别
    Kali Linux自定义分辨率设置
    CentOS最小化安装后配置NAT网络模式
    CentOS7.5安装及最小安装后联网配置--联网配置
    CentOS7.5安装及最小安装后联网配置--系统安装
    基数排序
    归并排序
    堆排序
    简单选择排序
  • 原文地址:https://www.cnblogs.com/hoiday/p/10166424.html
Copyright © 2011-2022 走看看