智能指针概念和使用

 

 

目录结构:

 

通过案例引入智能指针

智能指针的作用

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

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

使用stlboost提供的标准智能指针类模板处理问题

 

 

通过案例引入智能指针

   

有如下的程序:

#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;

}

 

使用stlboost提供的标准智能指针类模板处理问题

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

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

 

使用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;

}

 

 

 

 

 

 

 

 

posted @ 2019-11-15 13:46  黄土塬  阅读(397)  评论(0编辑  收藏  举报