C++之中类类型的指针管理方法(2)句柄类的使用

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

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

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

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

  1. /*  
  2. * Handle Class Sample  句柄类示例 
  3. */  
  4.   
  5. #ifndef SAMPLE_H   
  6. #define SAMPLE_H   
  7.   
  8. #include <iostream>   
  9. #include <stdexcept>   
  10. using namespace std;  
  11.    
  12. //基类   
  13. class Item_base  
  14. {  
  15. public:  
  16.     //基类的虚函数,用于智能地复制对象   
  17.     virtual Item_base* clone() const  
  18.     {  
  19.         return new Item_base( *this );  
  20.     }  
  21. };  
  22.   
  23.   
  24. //子类   
  25. class Bulk_item: public Item_base  
  26. {  
  27.     //子类的虚函数的重载,用于智能地复制对象   
  28.     virtual Bulk_item* clone() const  
  29.     {  
  30.         return new Bulk_item( *this );  
  31.     }  
  32. };  
  33.   
  34. //子类的子类   
  35. class Sales_item: public Bulk_item  
  36. {  
  37. public:  
  38.     //默认构造函数,用来初始化一个引用计数器   
  39.     Sales_item(): p( 0 ) , use( new size_t( 1 ) ) { cout << "Sales_item的引用计数器初始化为1" << endl; }  
  40.       
  41.     //带有一个参数的,且该参数为基类引用的构造函数  
  42.    // clone函数真实巨牛无比啊,这样带参数构造函数,就完成了对于未知类型的复制
  43.     Sales_item( const Item_base& ):p(item.clone()),use(new std::size_t(1)){};
  1.     //复制构造函数,需要注意的是,每复制一次就需要增加引用计数一次   
  2.     Sales_item( const Sales_item &i ): p( i.p ) , use( i.use ) { ++*use; cout << "由于采用了复制构造函数,Sales_item类型的对象引用计数为:" << *use << endl;} //也可以这样写   
  3.     //Sales_item( const Sales_item &i ): p( i.clone() ) , use( new size_t( 1 ) ) { ++*use; }   
  4.       
  5.       
  6.     //析构函数,析构的时候会判断是否能够释放指针所指向的数据   
  7.     ~Sales_item() { cout << "在析构函数中:"; decr_use(); }  
  8.       
  9.       
  10.     //赋值操作符重载   
  11.     Sales_item& operator= ( const Sales_item& );  
  12.       
  13.     //访问操作符重载   
  14.     const Item_base* operator-> () const  
  15.     {  
  16.         if( p )  
  17.         {  
  18.             return p;  
  19.         }  
  20.         else  
  21.         {  
  22.             throw logic_error( "p指针错误" );  
  23.         }  
  24.     }  
  25.       
  26.     //解引用操作符重载   
  27.     const Item_base& operator* () const  
  28.     {  
  29.         if( p )  
  30.         {  
  31.             return *p;  
  32.         }  
  33.         else  
  34.         {//重载虚函数,用于智能地复制对象   
  35.             throw logic_error( "p指针错误" );  
  36.         }  
  37.     }  
  38.       
  39.       
  40.     //重载虚函数,用于智能地复制对象   
  41.     /* 
  42.     virtual Sales_item* clone() const 
  43.     { 
  44.         return new Sales_item( *this ); 
  45.     } 
  46.     */  
  47.       
  48. private:  
  49.     //两个指针存储着引用计数器以及数据的指针   
  50.     Item_base *p;  
  51.     size_t *use;  
  52.       
  53.     //减少引用   
  54.     void decr_use()  
  55.     {  
  56.         cout << "在 dec_use函数中引用计数减少了,当前计数值为:" << *use - 1 << endl;  
  57.         if( --*use == 0 )  
  58.         {  
  59.             delete p;  
  60.             delete use;  
  61.             cout << "在 dec_use函数中计数器减为0,释放对象" << endl;  
  62.         }  
  63.           
  64.     }  
  65. };  
  66.   
  67.   
  68. //赋值操作符重载,每次复制都会增加引用计数   
  69. Sales_item& Sales_item::operator= ( const Sales_item &si )  
  70. {  
  71.     cout << "由于采用类赋值操作,";  
  72.     cout << "被赋值的对象的引用计数为:" << *si.use ;  
  73.     cout << "即将被赋值的对象的引用计数为:" << *use << endl;  
  74.     //这里需要特别注意的就是待复制的对象的计数器需要加1而被赋值的对象需要减1     
  75.       
  76.     //增加被复制对象的引用计数   
  77.     ++*si.use;  
  78.     cout << "被赋值的对象的赋值之后的引用计数为:" << *si.use << endl;  
  79.     //将即将被赋值的对象的引用计数减1   
  80.     decr_use();  
  81.     cout << " 即将被赋值的对象赋值之后的引用计数为:" << *use << endl;  
  82.       
  83.       
  84.     //复制指针   
  85.     p = si.p;  
  86.     use = si.use;  
  87.       
  88.     //返回   
  89.     return *this;  
  90. }  
  91.   
  92.   
  93. #endif //SAMPLE_H  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值