您好,欢迎来到伴沃教育。
搜索
您的当前位置:首页C++数据结构--智能指针

C++数据结构--智能指针

来源:伴沃教育

1、智能指针的示例

A.内存泄漏

1.动态申请堆空间,用完后不归还

2.C语言中没有垃圾回收的机制

3.指针无法控制所指堆空间的生命周期

B.当代C软件平台中的智能指针

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

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

3.杜绝指针运算和指针比较

智能指针的设计方案

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

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

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

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

Point类实现代码如下

#include "Object.h"

namespace MyLib
{
    template <typename T>
    class Pointer:public Object
    {
    protected:
        T* m_pointer;
    public:
        Pointer(T* p=NULL)
        {
            m_pointer=p;
        }

        T* operator->()
        {
            return m_pointer;
        }

        const T& operator*()const
        {
            return *m_pointer;
        }

        const T* operator->()const
        {
            return m_pointer;
        }

        T& operator*()
        {
            return *m_pointer;
        }

        bool isNull()const
        {
            return (m_pointer==NULL);
        }

        T* get()const
        {
            return m_pointer;
        }
    };
}

SmartPoint的实现代码

#include "Pointer.h"
namespace MyLib
{
    /*智能指针的实现(智能指针只能指向单个变量或者单个对象)
        1.指针生命周期结束时主动释放空间
        2.一片堆空间最多只能由一个指针标识
        3.杜绝指针运算和指针比较

        设计方案
        1.通过类模板描述指针的行为(能够定义不同类型的指针对象)
        2.重载指针特征操作符(->和*)(利用对象模拟原生指针的行为)
    */
    template<typename T>//创建的指针可以指向任意的类型
    class SmartPointer:public Pointer<T>//定义的类
    {
    public:
        SmartPointer(T* p=NULL):Pointer<T>(p)
        {

        }

        SmartPointer(const SmartPointer<T>& obj)
        {
            this->m_pointer=obj.m_pointer;

            const_cast<SmartPointer<T>&>(obj).m_pointer=NULL;
        }

        SmartPointer<T>& operator =(const SmartPointer<T>& obj)
        {
            if(this!=obj)
            {
                T* p=this->m_pointer;

                //delete m_pointer;

                this->m_pointer=obj.m_pointer;

                const_cast<SmartPointer<T>&>(obj).m_pointer=NULL;

                delete p;
            }


            return *this;
        }

        ~SmartPointer()
        {
            delete this->m_pointer;
        }
    };
}

在使用智能指针(SmartPointer)替换单链表(LinkList)中的原生指针会出现问题,可以发现在SmartPointer的设计方案中(一片堆空间最多只能由一个指针标识)

2、SharedPoint的实现

SharedPoint设计要点

A.类模板

通过计数机制(ref)标识堆内存

1.堆内存被指向时:ref++

2.指针被置空时:ref–

3.ref==0:释放堆内存

计数机制的原理

同时由于SharedPoint支持多个对象同时指向一片堆空间,因此,必须支持比较操作

实现的代码如下

#include "Pointer.h"
#include <cstdlib>
#include "Exception.h"

namespace MyLib
{
    template<typename T>
    class SharedPointer :public Pointer<T>
    {
    protected:
        int* m_ref;

        void assign(const SharedPointer<T>& obj)
        {
            this->m_ref=obj.m_ref;
            this->m_pointer=obj.m_pointer;

            if(this->m_ref)
            {
                (*this->m_ref)++;
            }
        }
    public:
        SharedPointer(T* p=NULL):m_ref(NULL)
        {
            if(p)
            {
                this->m_ref=static_cast<int*>(std::malloc(sizeof(int)));//在堆空间申请一个四个字节
                if(this->m_ref)//内存申请成功的情况下的操作
                {
                    *(this->m_ref)=1;
                    this->m_pointer=p;
                }
                else
                {
                    THROW_EXCEPTION(NoEoughMemoryException,"...");
                }
            }
        }

        SharedPointer(const SharedPointer<T>& obj):Pointer<T>(NULL)
        {
            //都指向了堆空间
            assign(obj);
        }

        SharedPointer<T>& operator=(const SharedPointer<T>& obj)
        {
            if(this!=&obj)//避免自赋值
            {
                clear();//在进行赋值之前  将当前的智能指针对象置空

                assign(obj);
            }

            return *this;
        }

        void clear()
        {
            T* toDel=this->m_pointer;
            int* ref=this->m_ref;

            this->m_pointer=NULL;
            this->m_ref=NULL;

            if(ref)
            {
                (*ref)--;

                if(*ref==0)
                {
                    free(ref);

                    delete toDel;
                }
            }
        }

        ~SharedPointer()
        {
            clear();
        }
    };

    template <typename T>
    bool operator == (const SharedPointer<T>& l,const SharedPointer<T>& r )
    {
        return (l.get()==r.get());
    }

    template <typename T>
    bool operator != (const SharedPointer<T>& l,const SharedPointer<T>& r )
    {
        return !(l==r);
    }
}

注意:

1.只能指针只能用来指向堆空间中的单个变量

2.不同类型的智能指针对象不能混合使用

3.不要使用delete释放智能指针指向的堆空间

3、小结

1.SharedPoint最大程度的模拟了原生指针的行为

2.计数机制确保多个智能指针合法的指向同一片堆空间

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

4.不同类型的智能指针不要混合使用

5.堆对象的生命周期由智能指针进行管理

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- bangwoyixia.com 版权所有 湘ICP备2023022004号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务