C++思考笔记-----Ruminations on C++ 之 被封装的指针----句柄

来源:互联网 发布:诺信威视软件下载 编辑:程序博客网 时间:2024/06/11 21:09

       前面一章刚学习了代理类,还说了它解决了什么样的问题,它怎么怎样的好.这一章立刻又遇到了问题,代理类确实很好的实现了对一类对象的统一管理,但对一弄些情况下.如,一个对象是很大的.大对象有个特点,点用资源多,拷贝它是要花费很大的空间和时间的.而代理类却大量的对原类进行了copy.所以问题就有了.当然,对于一些小类,而又需要很好的管理他们,代理类依然是很好用的...


-------------------------------------------------------------------------------------------------------------------------------


句柄类解决的问题.


     句柄类,也并不只是为了解决代理的问题,那只是很小的一部分..可是想像这样一种情形,比如,我有一个类封装了对数据库的操作.而其它两个类都需要对其进行调用,(这是很常见的问题.),所要做的就是把数据库类的对象的地址给另外两个类,这样功能是实现了,可是当我对数据库存操作完成需要释放数据库对象的时候,就是个问题了.(当然,不去释放是不被允许的),

 

     很容易想到解决的方法,,可以在前面的数据库类里加一个记录此对象被引用次数的私有成员,并提供相应的访问接口.问题解决..

 

-------------------------------------------------------------------------------------------------------------------------------

 

我对句柄的认识,

 

     在我看来,句柄就是我们起的一个名子,我们为了正好的管理我们的指针(内存),上面那样只在类里加一个记数器,我们依然可以把这个过程叫做句柄,(其实,指针还是那个指针,没有什么特别的).

 

     如果把上面说的句柄看成是一个厂义上的概念,那么接下来要总结一下狭义概念了.(真正做到对指针对内存管理的封装,) 

 

     我大一下半年,我在学习mfc和win32的时候第一次听到句柄这个概念,对于新概念,当然是很迷惑的,当时学长告诉我,就把它理解成指针(当时的水平,根本没有内存管理,软件安全方面的觉悟吧,所以,理解成指针也不会有什么问题),到后来接触的越来越多,Thinking in C++,C++ primary,和其它的一些书,还有做其它项目时候网络上偶尔相遇,再到现在读的此书,每一次的经历,都会有一个认识上的提升,(当然,以后还会继续提升).

 

     下面是一些经典的封装:

 

      class Handle {

      public:

           Handle();

           Handle(const AClass &);

           Handle(const AClass *);

           Handlw& operator=(const Handle&);

           ~Handle()

   {

if(--count==0)

     delete p;

   }

      private:

           //...

   AClass *p;

      };

 

大部分面向对象的句柄(类)大概都包含这些属性,许多封闭的不同之处就在于,计数器count所放的位置,

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

 

1>count作为Handle类的static 公有成员.

 

         类的static成员的作用就是站在class的高度(而不属于某个实例),所以可以用它来作计数器,,

 

2>count作为原类的一个成员变量,用它来统计指向原类某个对象的指针个数..

 

         这种方法与方法1>的区别可能不好看出...现在举一个例子,就能很容易找到它们之间的不同.

 

##:   第一种方法计数器是针对这个类的,第二种是针对,这个类的每一个对象的.

 

         第一种方法要求这个类只能被实例化一次,为什么这么说呢..如果你实例化两次(多次),那么它们会共用一个计数器,(这显然是很危险的),

所以用这种方法的前提是,我这个类只要一个实例就能够完成任务,,而且要在原类中加个static控制开关,当有一个实例了,就把开关关掉,防止再次被实例化

 

         第二种方法就没有上面的问题:但是析构函数要改为:

 

                Handle::~Handle()

     {

count =p.getCount();//这里count 为类的私有成员,用访问接口访问

if(--count==0)

          delete p;

else

     p.setCount(count);

     }

这样count只赖于特定的对象,,就可以出现程序中多个实例并存了.

 

3>另外定义一个伴随类,类只有原对象(引用)和记数器,Handle类和上面基本相同,只是没了直接的原来指针,取而代之的是原类的伴随类指针,

 

      这种方法,也有个好处(当然,没有好处,那就没必要用它了.),就是原类中只有实现自己功能的成员,而没有外来成员(count)了,外来成员被统一放到伴随类里.


      实现方法和2>差不多,这里就不写示例了....

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

 

其实,实现方法,还有很多...有兴趣的可以一起讨论.以后遇到了经典的,还会再行整理...

原创粉丝点击