• 第九课、智能指针示例------狄泰软件学院


    一、内存泄漏(臭名昭著的bug)

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

    (2)、c++语言中没有垃圾回收机制

    (3)、指针无法控制所指向的堆空间生命周期(如局部指针生命周期结束了堆空间的生命周期还未结束

    二、智能指针

    1、当代c++平台的智能指针

    (1)、指针生命周期结束时主动释放堆空间

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

    (3)、杜绝指针运算和指针比较

    2、智能指针的设计方案

    (1)、通过类模板描述指针的行为:能够定义不同类型的指针变量

    (2)、重载指针特征操作符(->和*):利用对象模拟原生指针的行为

    3、下面说明用c++来实现智能指针的具体做法

    1、为了达到指针生命周期结束时主动释放堆空间的目的,需要在析构函数中将指针删除

      SmartPoiter(T* p = NULL)
        {
            m_pointer = p;//开始时指向NULL
        }
    
        T* operator -> ()
        {
            return m_pointer;
        }
    
        T& operator * ()
        {
            return *m_pointer;
        }
    
        bool isNull()
        {
            return (m_pointer == NULL);
        }
    
        T* get()
        {
            return m_pointer;
        }
    
        ~SmartPoiter()
        {
            delete m_pointer;//析构函数中删除原生指针
        }

    2、而要达到一片内存只有一个指针管理的目的,必须在拷贝构造函数和赋值操作符处做处理

      SmartPoiter(const SmartPoiter<T>& obj)
        {
            m_pointer = obj.m_pointer;
            const_cast<SmartPoiter<T>&>(obj).m_pointer = NULL;//因为obj是const属性,不能做左值,需先进行强制类型转换
        }
    
        SmartPoiter<T>& operator = (const SmartPoiter<T>& obj)
        {
            if( this != &obj )
            {
                delete m_pointer;
                m_pointer = obj.m_pointer;
                const_cast<SmartPoiter<T>&>(obj).m_pointer = NULL;
            }
    
            return *this;
        }

    3、而要实现不能进行指针运算和指针比较则非常容易:不重载相应的操作符即可(如不重载++操作符和==操作符等)

    三、完整代码

    #ifndef SMARTPOINTER_H
    #define SMARTPOINTER_H
    
    namespace DTLib
    {
    template <typename T>
    class SmartPoiter
    {
    protected:
        T* m_pointer;
    public:
        SmartPoiter(T* p = NULL)
        {
            m_pointer = p;
        }
    
        SmartPoiter(const SmartPoiter<T>& obj)
        {
            m_pointer = obj.m_pointer;
            const_cast<SmartPoiter<T>&>(obj).m_pointer = NULL;
        }
    
        SmartPoiter<T>& operator = (const SmartPoiter<T>& obj)
        {
            if( this != &obj )
            {
                delete m_pointer;
                m_pointer = obj.m_pointer;
                const_cast<SmartPoiter<T>&>(obj).m_pointer = NULL;
            }
    
            return *this;
        }
    
        T* operator -> ()
        {
            return m_pointer;
        }
    
        T& operator * ()
        {
            return *m_pointer;
        }
    
        bool isNull()
        {
            return (m_pointer == NULL);
        }
    
        T* get()
        {
            return m_pointer;
        }
    
        ~SmartPoiter()
        {
            delete m_pointer;
        }
    };
    }
    
    #endif // SMARTPOINTER_H
    SmartPointer.h
    #include <iostream>
    #include "SmartPointer.h"
    
    using namespace std;
    using namespace DTLib;
    
    class Test
    {
    public:
        Test()
        {
            cout << "Test()" << endl;
        }
    
        ~Test()
        {
            cout << "~Test" << endl;
        }
    };
    
    int main()
    {
        SmartPoiter<Test> p1 = new Test();
        //SmartPoiter<Test> p2 = p1;
        SmartPoiter<Test> p2;
        p2 = p1;
    
        cout << "p1=" << p1.isNull() << endl;
        cout << "p2=" << p2.isNull() << endl;
    
        //p1++;//不能进行指针运算,因为没有重载相应的操作符
        return 0;
    }

    注:智能指针使用军规:只能用来指向堆空间的单个对象或者单个变量

    四、小结

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

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

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

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

     

  • 相关阅读:
    VS2010开发工具使用技巧<之简单讲解>
    JS中的数学计算<之简单实例讲解>
    让DIV中文字换行显示
    VS2010编写WebService与在IIS的发布<之简单讲解>
    JSON.parse 与 eval() 对于解析json的问题
    [字符串]与[数组]的互相转换
    A标签实现文件下载功能
    "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突问题
    IE开发人员工具之实用功能讲解
    CSS选择器 < ~ +
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6816334.html
Copyright © 2020-2023  润新知