zoukankan      html  css  js  c++  java
  • C++学习基础七——深复制与浅复制

    一、深复制与浅复制基本知识

    深复制和浅复制,又称为深拷贝和浅拷贝。
    深复制和浅复制的区别如下图1所示:
              图1
    图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量,
    当深复制时,A中的指针str与B中的指针str指向不同的地址,只是地址所指向的数据相同。
    当浅复制时,A中的指针str与B中的指针str指向相同的地址。
     
    1.浅复制:如果我们自己不实现复制构造函数,则C++会自动合成一个复制构造函数,又称为浅复制构造函数。
    2.深复制:如果使用指针或者系统资源(如数据库,流对象等),则需要自己实现深复制的复制构造函数。
    3.深复制与浅复制的代码区别:
     1 Demo(const Demo &other)
     2 {
     3    this->id= other.id;
     4     this->str = new char[1024];//深复制 ,该指针与 other内的指针变量指向两个不同的地址,只是数据相同 
     5     strcpy(this->str,other.str);
     6 } 
     7 或者
     8 Demo(const Demo &other)
     9 {
    10      this->id= other.id;
    11       //深复制 ,该指针与 other内的指针变量指向两个不同的地址,只是数据相同 
    12    this->str = other.str;
    13 } 
    14 Demo(const Demo &other)
    15 {
    16      this->id= other.id;
    17      strcpy(this->str,other.str);//浅复制
    18 }
    4.如果自定义的类中包含指针,则应该自己实现深复制的复制构造函数,赋值操作符和析构函数。

    二、管理指针成员

    浅复制时因为两个指针指向相同的地址,很有可能出现野指针的情况;
    深复制不会出现野指针,但会出现很多相同的对象,浪费内存。
    如何有效的使用指针成员呢?管理指针成员的三个方法如图2所示:
        图2
    三种方式的具体区别如图3所示:
                    图3
    总结:智能指针其实是浅复制,只是智能指针不会产生野指针,而浅复制会产生野指针。
      1 #include <iostream>
      2 
      3 using namespace std;
      4 
      5 class ADemo
      6 {
      7 public:
      8     ADemo(int v, const int &p)
      9     {
     10         val = v;
     11         ptr = new int(p);
     12     }
     13     ~ADemo()
     14     {
     15         delete ptr;
     16     }
     17     
     18     ADemo(const ADemo &other)
     19     {
     20         val = other.val;
     21         ptr = new int;
     22         *ptr = *other.ptr;//深复制 
     23     }
     24     
     25     ADemo& operator=(const ADemo &other)
     26     {
     27         val = other.val;
     28         ptr = new int;
     29         *ptr = *other.ptr;//深复制 
     30         return *this;
     31     }
     32     
     33     int get_ptr_val()
     34     {
     35         return *ptr;
     36     }
     37     void set_ptr(int v)
     38     {
     39         *ptr = v;
     40     }
     41 private:
     42     int val;
     43     int *ptr;    
     44 };
     45 
     46 class BDemo
     47 {
     48     public:
     49     BDemo(int v, const int &p)
     50     {
     51         val = v;
     52         ptr = new int(p);
     53     }
     54     ~BDemo()
     55     {
     56         delete ptr;
     57     }
     58     
     59     BDemo(const BDemo &other)
     60     {
     61         val = other.val;
     62         ptr = other.ptr;//浅复制 
     63     }
     64     
     65     BDemo& operator=(const BDemo &rig)
     66     {
     67         val = rig.val;
     68         ptr = rig.ptr;//浅复制 
     69         return *this;
     70     }
     71     
     72     int get_ptr_val()
     73     {
     74         return *ptr;
     75     }
     76     void set_ptr(int v)
     77     {
     78         *ptr = v;
     79     }
     80 private:
     81     int val;
     82     int *ptr;
     83     
     84 };
     85 
     86 //====================智能指针start============
     87 class U_Ptr
     88 {
     89     friend class CDemo;
     90 private:
     91     int *ptr;
     92     size_t use;
     93     U_Ptr(int *p,int u)
     94     {
     95         this->ptr = p;
     96         use = u;
     97     }    
     98     ~U_Ptr()
     99     {
    100         delete ptr;
    101     }
    102 } ;
    103 
    104 class CDemo
    105 {//智能指针 
    106 public:
    107     CDemo(const int &p,int v)
    108     {
    109         ptr = new U_Ptr(new int(p),1);
    110         val = v;
    111     }
    112     ~CDemo()
    113     {
    114         if(--ptr->use == 0)delete ptr;
    115     }
    116     
    117     CDemo(const CDemo &other)
    118     {
    119         ++ptr->use;//多了一个对象使用 
    120         val = other.val;
    121         ptr = other.ptr;//浅复制 
    122     }
    123     CDemo& operator=(const CDemo &rig)
    124     {
    125         ++rig.ptr->use;
    126         if(--ptr->use == 0)delete ptr;
    127         
    128         val = rig.val;
    129         ptr = rig.ptr;//浅复制 
    130         return *this;
    131     } 
    132     
    133     void set_Ptr_val(int v)
    134     {
    135         *ptr->ptr = v;
    136     }
    137     
    138     int get_ptr_val()
    139     {
    140         return *ptr->ptr;
    141     }
    142 private:
    143     int val;
    144     U_Ptr *ptr;
    145 };
    146 
    147 void test_ShenCopy()
    148 {
    149     int prr = 20;
    150     ADemo a(10,prr);
    151     ADemo b = a;
    152     cout<<"a = "<<a.get_ptr_val()<<endl;
    153     cout<<"b = "<<b.get_ptr_val()<<endl;
    154     cout<<"修改之后:"<<endl;
    155     a.set_ptr(40);
    156     cout<<"a = "<<a.get_ptr_val()<<endl;
    157     cout<<"b = "<<b.get_ptr_val()<<endl;
    158 } 
    159 void test_QianCopy()
    160 {
    161     
    162     int prr = 40;
    163     BDemo a(50,prr);
    164     BDemo b = a;
    165     cout<<"a = "<<a.get_ptr_val()<<endl;
    166     cout<<"b = "<<b.get_ptr_val()<<endl;
    167     cout<<"修改之后:"<<endl;
    168     b.set_ptr(80);
    169     cout<<"a = "<<a.get_ptr_val()<<endl;
    170     cout<<"b = "<<b.get_ptr_val()<<endl;
    171 } 
    172 
    173 void test_smart()
    174 {
    175     int prr = 90;
    176     CDemo a(100,prr);
    177     CDemo b = a;
    178     cout<<"a = "<<a.get_ptr_val()<<endl;
    179     cout<<"b = "<<b.get_ptr_val()<<endl;
    180     cout<<"修改之后:"<<endl;
    181     b.set_Ptr_val(180);
    182     cout<<"a = "<<a.get_ptr_val()<<endl;
    183     cout<<"b = "<<b.get_ptr_val()<<endl;
    184 }
    185 int main()
    186 {
    187     cout<<"深复制:"<<endl;
    188     test_ShenCopy();
    189     cout<<endl<<"浅复制:"<<endl;
    190     test_QianCopy();
    191     cout<<endl<<"智能指针:"<<endl;
    192     test_smart();
    193     return 0;
    194 }
  • 相关阅读:
    0034 CSS精灵技术:sprite(重点)
    0033 溢出的文字省略号显示:white-space、overflow、text-overflow
    0032 垂直对齐:vertical-align(图片、表单和文字对齐,去除图片底侧空白缝隙)
    0031 CSS用户界面样式:鼠标样式cursor、轮廓线 outline、防止拖拽文本域resize
    0030 元素的显示与隐藏:dispaly、visibility、overflow
    0029 css定位:相对、绝对、固定、绝对定位盒子居中、z-index、绝对定位改变display属性、案例
    0027 chrome调试工具
    0026 页面布局流程
    0025 CSS属性书写顺序
    0024 Photoshop 切图
  • 原文地址:https://www.cnblogs.com/calence/p/5855015.html
Copyright © 2011-2022 走看看