zoukankan      html  css  js  c++  java
  • C++中的深拷贝与浅拷贝

    首先来介绍一下深拷贝和浅拷贝的概念

    一.浅拷贝

    浅拷贝:如果用默认的拷贝构造函数(赋值函数)去赋值有指针类型的成员变量的对象,将会使两个对象
    的指针地址也是一样的,也就是说这两个对象的指针成员变量指向的是相同的地址。

    如果程序中没有写拷贝构造函数,则会去调用默认构造函数,这个属于浅拷贝,是单纯的赋值关系,是将数据逐个的复制给拷贝的对象,

    指向的是同一块内存,很容易造成堆区的内存重复释放的问题,深拷贝则是来解决这一问题的。

    二.深拷贝
    深拷贝:每个对象拥有自己的资源,此时需要显示提供拷贝构造函数和赋值函数。

    拷贝构造函数的格式

    Person(const Person& p)    //Person是一个类

    {

    cout <<"Person的拷贝构造函数" << endl;

    }

    下面用程序来解释一下

    首先用浅拷贝

     1 #include<iostream>                                                                                                                  
     2 
     3 using namespace std;
     4 
     5 class Person
     6 {
     7     public:
     8     
     9     Person(int age ,int height)
    10     {   
    11         m_age = age;    
    12         m_height = new int(height); 
    13         cout << "Person的构造函" << endl;
    14     }
    15 
    16 //  Person(const Person& p)
    17 //  {
    18     //  cout << "拷贝构造函数" << endl;
    19     //  m_age = p.m_age;
    20 //      m_height = new int(*p.m_height);
    21 //  }
    22     
    23     ~Person()
    24     {   
    25         if(m_height != NULL)
    26         {   
    27             delete m_height;
    28             m_height = NULL;
    29         }
    30         cout << "Person的析构函数" << endl;
    31     }
    32     
    33     int m_age;
    34     int *m_height;
    35 };
    36 
    37 void test1()
    38 {
    39     Person p1(18 , 160);
    40     cout << "年龄:" << p1.m_age << "身高:" << *p1.m_height <<  endl;
    41     Person p2(p1);
    42     cout << "年龄" << p2.m_age << "身高:" << *p2.m_height << endl;
    43 }
    44 
    45 int main(int argc , char **argv)
    46 {
    47     test1();
    48     return 0;
    49 }                                                         

    利用的是默认拷贝构造,所以称为浅拷贝,我们就会发现一个问题,调用完对象之后,进行析构的时候发现堆区的内存被释放了两次,重复释放了

    这就造成了程序出错,需要用深拷贝去解决浅拷贝的问题。

    深拷贝

    1 #include<iostream>                                                                                                                  
     2 
     3 using namespace std;
     4 
     5 class Person
     6 {
     7     public:
     8     
     9     Person(int age ,int height)
    10     {   
    11         m_age = age;    
    12         m_height = new int(height); 
    13         cout << "Person的构造函" << endl;
    14     }
    15 
    16   Person(const Person& p)
    17   {
    18       cout << "拷贝构造函数" << endl;
    19       m_age = p.m_age;
    20       m_height = new int(*p.m_height);
    21   }
    22     
    23     ~Person()
    24     {   
    25         if(m_height != NULL)
    26         {   
    27             delete m_height;
    28             m_height = NULL;
    29         }
    30         cout << "Person的析构函数" << endl;
    31     }
    32     
    33     int m_age;
    34     int *m_height;
    35 };
    36 
    37 void test1()
    38 {
    39     Person p1(18 , 160);
    40     cout << "年龄:" << p1.m_age << "身高:" << *p1.m_height <<  endl;
    41     Person p2(p1);
    42     cout << "年龄" << p2.m_age << "身高:" << *p2.m_height << endl;
    43 }
    44 
    45 int main(int argc , char **argv)
    46 {
    47     test1();
    48     return 0;
    49 }       

    加入了拷贝构造函数,在进行拷贝的时候,在堆区各自分配了内存,防止了浅拷贝内存重复释放的问题。

    上面就很好的解释了深拷贝和浅拷贝的应用和理解。

  • 相关阅读:
    安装的时候,突然安装程序关闭,的灵异问题。
    CSAPP阅读笔记(1)-序
    CSAPP阅读笔记(2)-虚存管理
    nafxcwd.lib(afxmem.obj) :error LNK2005:"void * __cdecl operator new(unsigned int)"
    Linux内核源代码情景分析读书笔记(5)-关于fork/clone/vfork
    [转]调试经验总结VC下的错误对话框
    IP数据包首部的校验和算法
    Matlab画图及生成exe文件
    VC++6.0中的new
    Linux内核模块编译、加载&卸载及查看运行结果
  • 原文地址:https://www.cnblogs.com/tanshengjiang/p/14391430.html
Copyright © 2011-2022 走看看