zoukankan      html  css  js  c++  java
  • 第九课、智能指针示例------狄泰软件学院

    一、内存泄漏(臭名昭著的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)、智能指针的意义在于最大程度避免内存问题

     

  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6816334.html
Copyright © 2011-2022 走看看