关闭

C++管理指针成员

标签: C#
454人阅读 评论(0) 收藏 举报

1、C++中一般采用下面三种方法之一管理指针成员:

    (1)指针成员采取常规行为。这样的类具有指针的所有缺陷:具有指针成员且使用默认复制构造函数和赋值操作符,无法避免悬垂指针(两个对象的指针成员指向同一内存,删除了其中一个指针指向的内存时,另一个指针将不再指向有效的内存空间)。

    (2)类可以实现所谓的"智能指针"行为。引入计数类,智能指针类将一个计数器与类的对象相关联。使用计数跟踪该类有多少个对象共享同一指针。当计数为0时,删除对象。

    (3)类采取值行为。采用重载的复制构造函数、赋值操作符和析构函数。

2、指针成员采取常规行为示例:两个指针指向同一块内存,会引起不可预料的后果

  1. #include "stdafx.h"  
  2. #include <string.h>  
  3. #include <iostream.h>  
  4.   
  5. class HasPtr  
  6. {  
  7. public:  
  8.     HasPtr(int *p,int i):ptr(p),val(i){}  
  9.   
  10.     int *get_ptr()const{return ptr;}  
  11.     int get_val()const{return val;}  
  12.   
  13.     void set_ptr(int *p){ptr=p;}  
  14.     void set_val(int i){val=i;}  
  15.   
  16.     int get_ptr_val()const{return *ptr;}  
  17.   
  18.     void set_ptr_val(int val)const{*ptr=val;}  
  19.   
  20. private:  
  21.     int *ptr;  
  22.     int val;  
  23. };  
  24.   
  25. int main(int argc, char* argv[])  
  26. {     
  27.     int *p=new int(10);  
  28.     cout<<p<<endl;  
  29.     HasPtr ptr(p,10);  
  30.     cout<<ptr.get_ptr()<<endl;  
  31.     delete p;  
  32.     cout<<ptr.get_ptr_val()<<endl;  //p和ptr中的指针指向同一对象。删除该对象后,ptr中的指针不再指向有效的对象。  
  33.     return 0;  
  34. }  

3、"智能指针"行为示例:注意构造函数

  1. #include "stdafx.h"  
  2. #include <string.h>  
  3. #include <iostream.h>  
  4.   
  5. class HasPtr;  
  6. //计数类U_Ptr所有成员均为private,将HasPtr设置为计数类的友元类,使其可以访问U_Ptr的成员  
  7. class U_Ptr  
  8. {  
  9.     friend class HasPtr;  
  10.     int *ip;  
  11.     size_t use;  
  12.     U_Ptr(int *p):ip(p),use(1){}  
  13.     ~U_Ptr()  
  14.     {  
  15.         delete ip;  
  16.     }  
  17. };  
  18.   
  19. class HasPtr  
  20. {  
  21. public:  
  22.     HasPtr(int *p,int i):ptr(new U_Ptr(new int(*p))),val(i){} //构造函数,创建新的U_Ptr对象  
  23.   
  24.     HasPtr(const HasPtr &orig):ptr(orig.ptr),val(orig.val){++ptr->use;} //复制构造函数,计数加1  
  25.   
  26.     HasPtr& operator=(const HasPtr &rhs)  //赋值操作符,左操作数计数减1,右操作数计数加1,如果左操作数减至0,则删除左操作数指向的对象  
  27.     {  
  28.         if (this!=&rhs)  
  29.         {  
  30.             ++rhs.ptr->use;  
  31.             if(--ptr->use==0)  
  32.                 delete ptr;  
  33.             ptr=rhs.ptr;  
  34.             val=rhs.val;  
  35.         }  
  36.         return *this;  
  37.     }  
  38.       
  39.     ~HasPtr() //析构函数,计数减1,如果计数减至0,就删除对象  
  40.     {  
  41.         if (--ptr->use==0)  
  42.         {  
  43.             delete ptr;  
  44.         }  
  45.     }  
  46.       
  47.     int *get_ptr()const{return ptr->ip;}  
  48.     int get_val()const{return val;}  
  49.       
  50.     void set_ptr(int *p){ptr->ip=p;}  
  51.     void set_val(int i){val=i;}  
  52.       
  53.     int get_ptr_val()const{return *ptr->ip;}  
  54.       
  55.     void set_ptr_val(int val){*ptr->ip=val;}  
  56.       
  57. private:  
  58.     U_Ptr *ptr;  
  59.     int val;  
  60. };  
  61.   
  62. int main(int argc, char* argv[])  
  63. {     
  64.     int *p=new int(10);  
  65.     cout<<p<<endl;  
  66.     HasPtr ptr(p,10);  
  67.     cout<<ptr.get_ptr()<<endl;        //两指针指向同一块内存  
  68.     cout<<ptr.get_ptr_val()<<endl;    
  69.       
  70.     delete p;  
  71.     return 0;  
  72. }  

4、定义值型类:三法则(赋值操作符、复制构造函数、析构函数)

  1. #include <string.h>  
  2. #include <iostream.h>  
  3.   
  4. class HasPtr  
  5. {  
  6. public:  
  7.     HasPtr(int *p,int i):ptr(new int(*p)),val(i){} //构造函数  
  8.       
  9.     HasPtr(const HasPtr &orig):ptr(new int(*orig.ptr)),val(orig.val){} //复制构造函数  
  10.       
  11.     HasPtr& operator=(const HasPtr &rhs)  //赋值操作符  
  12.     {  
  13.         if (this!=&rhs)  
  14.         {  
  15.             ptr=new int(*rhs.ptr);  
  16.             val=rhs.val;  
  17.         }  
  18.         return *this;  
  19.     }  
  20.       
  21.     ~HasPtr(){delete ptr;}  //析构函数  
  22.       
  23.     int *get_ptr()const{return ptr;}  
  24.     int get_val()const{return val;}  
  25.       
  26.     void set_ptr(int *p){ptr=p;}  
  27.     void set_val(int i){val=i;}  
  28.       
  29.     int get_ptr_val()const{return *ptr;}  
  30.       
  31.     void set_ptr_val(int val)const{*ptr=val;}  
  32.       
  33. private:  
  34.     int *ptr;  
  35.     int val;  
  36. };  
  37.   
  38. int main(int argc, char* argv[])  
  39. {     
  40.     int *p=new int(10);  
  41.     cout<<p<<endl;  
  42.     HasPtr ptr(p,10);  
  43.     cout<<ptr.get_ptr()<<endl;       //p与ptr的指针不是指在同一块内存,但是所指向的对象内容是一样的  
  44.     delete p;  
  45.     cout<<ptr.get_ptr_val()<<endl;    
  46.     return 0;  
  47. }  
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:98195次
    • 积分:2994
    • 等级:
    • 排名:第12141名
    • 原创:209篇
    • 转载:19篇
    • 译文:0篇
    • 评论:12条
    最新评论