• C++管理指针成员


    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. }  
  • 相关阅读:
    indy Sftp 编程 ftp安全访问
    关于MySql里的字段
    php---魔术方法(__tostring(),__set_state())
    看了这个才发现jQuery源代码不是那么晦涩
    JS的Document属性和方法小结
    JS的Document属性和方法
    原始JS选择器使用方法总结
    docker 镜像配置
    Docker部署SpringBoot项目
    springboot 和spring cloud 博客分享
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6921289.html
Copyright © 2020-2023  润新知