数据结构--另一种智能指针-SharedPointer

来源:互联网 发布:二次元网络漫画图片 编辑:程序博客网 时间:2024/05/29 02:50

上一篇讲了最多只能由一个指针标识堆空间的SmartPointer,本篇讲解另一种智能指针--SharedPointer。

设计要点:

使用类模板实现。

继承自Pointer类

通过计数机制(ref)标识堆空间:被指向时ref++;指向的指针被置空时ref--;当计数变量ref为0时堆空间应该被释放。所以计数变量和堆空间对象是绑定在一起。

由于SharedPointer支持多个对象同时指向一片堆空间,所以需要支持比较操作,所以需要实现比较操作符重载。

由于const对象会使用指针操作符,所以需要重载const版本的(->)和(*)操作符重载。

由于需要重载比较操作符,需要将Pointer类的get函数和isNull函数做成const成员函数。

SharedPointer类声明及完整实现:

 template <typename T>    class SharedPointer : public Pointer<T>    {      protected:        int* m_ref;//计数变量    public:        SharedPointer(T* p = NULL) : m_ref(NULL)        {            if(p)            {                this->m_ref = static_cast<int*>(malloc(sizeof(int)));                if(this->m_ref)                {                    (*this->m_ref) = 1;//申请空间成功后表示已经有指针指向它,计数变量加1。                    this->m_pointer = p;                }                else//抛出异常                {                    THROW_EXCEPTION(NoEnoughMemoryException,"No enough memory to create...");                }            }        }        SharedPointer(const SharedPointer<T>& obj):Pointer<T>(NULL)//拷贝构造,拷贝成功后计数变量加1        {            this->m_ref = obj.m_ref;            this->m_pointer = obj.m_pointer;            if(this->m_ref)                (*this->m_ref)++;        }        SharedPointer<T>& operator= (const SharedPointer<T>& obj)//赋值操作符重载,赋值成功后计数变量加1        {            if(this != &obj)            {                clear();//清理当前指向                this->m_pointer = obj.m_pointer;//重新赋值                this->m_ref = obj.m_ref;                (*this->m_ref)++;            }            return *this;        }        void clear()//清除当前对象指向的空间,当计数变量为0时释放堆空间和计数变量占用的空间        {            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)//const对象只能调用const成员函数    {        return !(l == r);    }


程序分析见注释内容。

SharedPointer最大程度的模拟了原生指针的行为。

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

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

实现了自动管理内存。

使用军规:

只能用来指向堆空间中的单个变量或对象,不能是栈等内存。

不同类型的智能指针对象不能混合使用,SmartPointer对象和SharedPointer对象不能混合使用。

在使用智能指针后不要使用delete释放智能指针指向的堆空间。



测试代码:

class Test : public Object{public:    int value;    Test():value(0)    {        cout << "Test()" << endl;    }    Test(int value)    {        this->value = value;        cout << "Test()" << endl;    }    ~Test()    {        cout << "~Test()" << endl;    }};int main(){    SharedPointer<Test> sp = new Test();    SharedPointer<Test> nsp = NULL;    nsp = sp;    cout << sp->value << endl;    cout << nsp->value << endl;    nsp->value = 100;    cout << sp->value << endl;    cout << nsp->value << endl;    cout << (sp == nsp) << endl;    nsp.clear();    cout << (sp == nsp) << endl;    cout << endl;     const SharedPointer <Test> pp = new Test(111);    //(pp->value) = 100;//const对象不能修改成员变量的值,可以加上mutable强制破除只读属性。    cout << pp->value << endl;

输出结果:

Test()
0
0
100
100
1
0

Test()
111
~Test()
~Test()

请自行对照结果分析原因。


小结:

这两篇内容重新设计了智能指针,使得智能指针在使用中更安全和方便。


阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 绞丝旁的字有哪些 绞丝旁加晋读什么 缘去掉绞丝旁是什么字 绞丝机 预绞丝 绞丝旁一个条 绞刀绞孔转速参考表 心如刀绞的意思 绞肉机刀头图片 绞刀图片 绞刀 绞刀秤 连杆铜套绞刀 拉肚子肚子疼的像刀绞 绞刑 绞刑是什么 绞刑架 绞刑的意思 绞刑师 春天的绞刑架 绞刑师by唇亡齿寒 绞刑架下的春天1一45集播放 绞刑架下的祈祷作品 绞刑架下的春天 第五人格内测绞刑架 乌龙绞柱 20吨回柱绞车 回柱绞车 紧致吸绞汁水顶撞宝贝马车 芊芊紧致吸绞汁水顶撞折磨 吸绞汁水紧致爸爸 紧致吸绞汁水顶撞1v1 紧致吸绞汁水顶撞h 宝贝紧致吸绞汁水顶撞 紧致吸绞汁水顶撞折磨图片 紧致吸绞汁水顶撞马背 紧致吸绞汁水顶撞宝贝公交车 章紧致吸绞汁水顶撞折磨 吸绞汁水紧致 绞牙避震 绞牙