ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

智能指针概念和使用

2019-11-15 13:55:02  阅读:342  来源: 互联网

标签:exam 概念 int 智能 new ptr 指针


 

 

目录结构:

 

一 通过案例引入智能指针

二 智能指针的作用

三 设计辅助类实现智能指针作用

四 设计类模板实现智能指针作用

五 使用stl和boost提供的标准智能指针类模板处理问题

 

 

一 通过案例引入智能指针

   

有如下的程序:

#include <iostream>

using namespace std;

 

class exam

{

         public:

                   exam(int *p):ptr(p){}

                   exam(exam &obj)

                   {

                            ptr = obj.ptr;

                   }

                   ~exam()

                   {

                            delete ptr;

                   }

 

         private:

                   int *ptr;

};

 

int main()

{

 

         exam obj1(new int(4));

         exam obj2(obj1);

         exam obj3(new int(10));

         obj3 = obj2;

 

         return 0;

}

 

程序中存在两个问题:

  1 程序运行出现段错误,double free错误

  2 同时也造成了内存泄露

 

为了较为方便解决类似上面的问题,引入了智能指针的概念

 

 

 

二  智能指针概念和作用

  以下关于智能指针说法来之网络,大家可以动手自己搜索进一步查找概念

   

  1 动态内存管理经常会出现两种问题:

    一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下就释放了它,就会产生引用非法内存的指针

 

  2 智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。

    智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象

 

  3 智能指针就是一个类,当超出了类的作用域是,类会自动调用析构函数,析构函数会自动释放资源

 

  4 编程中出现问题:

      第一是创建new之后,忘记了delete;

      第二是,多个指针指向一个new的空间,但是其中的一个delete之后,剩下的依然去访问。

             然后出现访问一个空指针的情况

  5 智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。

    智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。

 

 以上的概念 作用或者实现叙述比较抽象,通过以下的代码进一步理解作用

 

三 设计辅助类实现智能指针作用

 

编程思想如下:

   1 每次创建类的新对象时,初始化指针并将引用计数置为1;

   2 当对象作为另一对象的副本而创建时,

     拷贝构造函数拷贝指针并增加与之相应的引用计数;

   3 对一个对象进行赋值时,

     赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;

   4 调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)

   

#include <iostream>

using namespace std;

 

 

class point

{

         friend class exam;

         point(int *pr):pin(pr),count(1){}

         ~point()

         {

                   delete pin;

         }

         int *pin;

         int count;

};

 

 

 

class exam

{

         public:

                   exam(int *p):ptr(new point(p)){}

                   exam(exam &obj)

                   {

                            ptr = obj.ptr;

                            ptr->count++;

                   }

        

                   exam &operator=(const exam &obj)

                   {

                            if(--ptr->count == 0)

                                     delete ptr;

 

                            ptr = obj.ptr;

                            ptr->count++;

                   }

 

                   ~exam()

                   {

                            if(--ptr->count == 0)

                                     delete ptr;

                   }

 

         private:

                   point *ptr;

};

 

int main()

{

 

         exam obj1(new int(4));

         exam obj2(obj1);

         exam obj3(obj2);

 

 

         exam obj4(new int(8));

         obj4 = obj3;

 

 

 

         return 0;

}

 

 

 解决了引例中的两个问题

 

四 设计类模板实现智能指针作用

  以上实现存在以下缺点:

    是每个含有指针的类的实现代码中都要自己控制引用计数,比较繁琐。

    特别是当有多个这类指针时,维护引用计数比较困难

 

 重新设计封装指针的类,

  为了避免上面方案中每个使用指针的类自己去控制引用计数,可以用一个类把指针封装起来。封装好后,这个类对象可以出现在用户类使用指针的任何地方,表现为一个指针的行为。我们可以像指针一样使用它,而不用担心普通成员指针所带来的问题,我们把这样的类叫句柄类

    模板类,可以封装各种类型的指针

 

#include <iostream>

using namespace std;

 

class stub

{

         public:

                   void print()

                   {

                            cout<<"stu:print"<<endl;

                   }

                   ~stub()

                   {

                            cout<<"stub:destructor"<<endl;

                   }

};

 

 

template<typename T>

class smartptr

{

         public:

                   smartptr(T *p = NULL):ptr(p),pUse(new size_t(1)){}

                   smartptr(const smartptr &src):ptr(src.ptr),pUse(src.pUse)

             {

                            ++*pUse;

             }

                   smartptr &operator=(const smartptr &rhs)

                   {

                            ++*rhs.pUse;

                            decrUse();

                            ptr = rhs.ptr;

                            pUse = rhs.pUse;

                            return *this;

                   }

 

                   T *operator->()

                   {

                            if(ptr)

                                     return ptr;

                   }

                   const T *operator->() const

                   {

                            if(ptr)

                                     return ptr;

                   }

 

                   T &operator*()

                   {

                            if(ptr)

                                     return *ptr;

                   }

                   const T &operator*()const

                   {

                            if(ptr)

                                     return *ptr;

                   }

                   ~smartptr()

                   {

                            decrUse();

                   }

 

 

         private:

                   void decrUse()

                   {

                            if(--*pUse == 0)

                            {

                                     delete ptr;

                                     delete pUse;

                            }

                   }

                   T *ptr;

                   size_t *pUse;

};

 

int main()

{

         /*

         smartptr<stub> t1(new stub);

         smartptr<stub> t2(t1);

         smartptr<stub> t3(new stub);

 

         t3 = t2;

         t1->print();

         (*t3).print();*/

 

         smartptr<string> t1(new string("mike"));

         smartptr<string> t2;

         cout<<*t1<<endl;

         cout<<t1->length()<<endl;

 

         t2 = t1;

 

         cout<<*t2<<endl;

         cout<<*t1<<endl;

 

 

 

 

         return 0;

}

 

五 使用stl和boost提供的标准智能指针类模板处理问题

   库的开发者:开发标准的实现智能指针的类模板

   用库中提供的智能指针模板类解决项目中的问题

 

1  使用stl提供的auto_ptr智能指针模板类:处理string *的情况

#include <iostream>

#include <memory>

using namespace std;

 

 

int main()

{

         auto_ptr<string> obj(new string("mike"));

         auto_ptr<string> obj1;

         cout<<*obj<<endl;

         cout<<obj->length()<<endl;

 

         obj1 = obj;

 

         cout<<*obj1<<endl;

         cout<<*obj<<endl;

 

 

         return 0;

}

 

2 使用boost库中提供shared_ptr智能指针模板类处理string *的案例:

 #include <iostream>

#include <memory>

#include <boost/smart_ptr.hpp>

using namespace std;

 

 

int main()

{

         boost::shared_ptr<string> obj(new string("mike"));

         boost::shared_ptr<string> obj1;

         cout<<*obj<<endl;

         cout<<obj->length()<<endl;

 

         obj1 = obj;

 

         cout<<*obj1<<endl;

         cout<<*obj<<endl;

 

 

         return 0;

}

 

 

 

 

 

 

 

 

标签:exam,概念,int,智能,new,ptr,指针
来源: https://www.cnblogs.com/huangtuyuan/p/11865907.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有