读C++ Primer 之句柄类


我们知道C++中最令人头疼的当属指针,如果您申请了对象却没有释放它,时间一长就会造成系统崩溃,大量的内存溢出使得您的程序的健壮性出现问题

而句柄类就是为了能够解决这一问题而出现的,句柄类有点类似于智能指针。

好了,废话不多说,我们来看代码

首先我们来看 sample.h文件的代码:

  1. /* 
  2. * author:xizero00 
  3. * mail:xizero00@163.com 
  4. * date:2011-08-07 20:11:24  
  5. * Handle Class Sample  句柄类示例 
  6. */  
  7.   
  8. #ifndef SAMPLE_H   
  9. #define SAMPLE_H   
  10.   
  11. #include <iostream>   
  12. #include <stdexcept>   
  13. using namespace std;  
  14.   
  15.   
  16.   
  17.   
  18. //基类   
  19. class Item_base  
  20. {  
  21. public:  
  22.     //基类的虚函数,用于智能地复制对象   
  23.     virtual Item_base* clone() const  
  24.     {  
  25.         return new Item_base( *this );  
  26.     }  
  27. };  
  28.   
  29.   
  30. //子类   
  31. class Bulk_item: public Item_base  
  32. {  
  33.     //子类的虚函数的重载,用于智能地复制对象   
  34.     virtual Bulk_item* clone() const  
  35.     {  
  36.         return new Bulk_item( *this );  
  37.     }  
  38. };  
  39.   
  40. //子类的子类   
  41. class Sales_item: public Bulk_item  
  42. {  
  43. public:  
  44.     //默认构造函数,用来初始化一个引用计数器   
  45.     Sales_item(): p( 0 ) , use( new size_t( 1 ) ) { cout << "Sales_item的引用计数器初始化为1" << endl; }  
  46.       
  47.     //带有一个参数的,且该参数为基类引用的构造函数   
  48.     Sales_item( const Item_base& );  
  49.       
  50.       
  51.       
  52.     //复制构造函数,需要注意的是,每复制一次就需要增加引用计数一次   
  53.     Sales_item( const Sales_item &i ): p( i.p ) , use( i.use ) { ++*use; cout << "由于采用了复制构造函数,Sales_item类型的对象引用计数为:" << *use << endl;} //也可以这样写   
  54.     //Sales_item( const Sales_item &i ): p( i.clone() ) , use( new size_t( 1 ) ) { ++*use; }   
  55.       
  56.       
  57.     //析构函数,析构的时候会判断是否能够释放指针所指向的数据   
  58.     ~Sales_item() { cout << "在析构函数中:"; decr_use(); }  
  59.       
  60.       
  61.     //赋值操作符重载   
  62.     Sales_item& operator= ( const Sales_item& );  
  63.       
  64.     //访问操作符重载   
  65.     const Item_base* operator-> () const  
  66.     {  
  67.         if( p )  
  68.         {  
  69.             return p;  
  70.         }  
  71.         else  
  72.         {  
  73.             throw logic_error( "p指针错误" );  
  74.         }  
  75.     }  
  76.       
  77.     //解引用操作符重载   
  78.     const Item_base& operator* () const  
  79.     {  
  80.         if( p )  
  81.         {  
  82.             return *p;  
  83.         }  
  84.         else  
  85.         {//重载虚函数,用于智能地复制对象   
  86.             throw logic_error( "p指针错误" );  
  87.         }  
  88.     }  
  89.       
  90.       
  91.     //重载虚函数,用于智能地复制对象   
  92.     /* 
  93.     virtual Sales_item* clone() const 
  94.     { 
  95.         return new Sales_item( *this ); 
  96.     } 
  97.     */  
  98.       
  99. private:  
  100.     //两个指针存储着引用计数器以及数据的指针   
  101.     Item_base *p;  
  102.     size_t *use;  
  103.       
  104.     //减少引用   
  105.     void decr_use()  
  106.     {  
  107.         cout << "在 dec_use函数中引用计数减少了,当前计数值为:" << *use - 1 << endl;  
  108.         if( --*use == 0 )  
  109.         {  
  110.             delete p;  
  111.             delete use;  
  112.             cout << "在 dec_use函数中计数器减为0,释放对象" << endl;  
  113.         }  
  114.           
  115.     }  
  116. };  
  117.   
  118.   
  119. //赋值操作符重载,每次复制都会增加引用计数   
  120. Sales_item& Sales_item::operator= ( const Sales_item &si )  
  121. {  
  122.     cout << "由于采用类赋值操作,";  
  123.     cout << "被赋值的对象的引用计数为:" << *si.use ;  
  124.     cout << "即将被赋值的对象的引用计数为:" << *use << endl;  
  125.     //这里需要特别注意的就是待复制的对象的计数器需要加1而被赋值的对象需要减1     
  126.       
  127.     //增加被复制对象的引用计数   
  128.     ++*si.use;  
  129.     cout << "被赋值的对象的赋值之后的引用计数为:" << *si.use << endl;  
  130.     //将即将被赋值的对象的引用计数减1   
  131.     decr_use();  
  132.     cout << " 即将被赋值的对象赋值之后的引用计数为:" << *use << endl;  
  133.       
  134.       
  135.     //复制指针   
  136.     p = si.p;  
  137.     use = si.use;  
  138.       
  139.     //返回   
  140.     return *this;  
  141. }  
  142.   
  143.   
  144. #endif //SAMPLE_H  
  • 1
  • 2
  • 下一页

相关内容