C++基础——深拷贝&浅拷贝

时间:2020-12-19 19:49:59
  • 在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存(在堆内存中)。
  • 可以理解为深拷贝是建了一个一模一样的副本,拷贝后共有两个实体对象。而浅拷贝只是一个链接,链接的目标还是原来的对象,实体对象数目还是一个。
  • 采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误。
  • 默认生成的拷贝构造函数是浅拷贝,对任何一个对象的改变都会影响到另一个对象。
  • 深拷贝典型函数:
    • class String
        {
         public:
         String(const String &other); //拷贝构造函数
         private:
         char *m_data; //用于保存字符串
        };
        
        String(const String &other)
        {
         int length = strlen(other.m_data);
         m_data = new char[length + 1];
         strcpy(m_data, other.m_data);
      }
  • 浅拷贝典型函数:

    • `
      class A
      {
      public:
      A() // 构造函数,p指向堆中分配的一空间
      {
      m_data = new char(100);
      printf(“默认构造函数\n”);
      }
      ~A() // 析构函数,释放动态分配的空间
      {
      if(m_data != NULL)
      {
      delete m_data;
      m_data = NULL;
      printf(“析构函数\n”);
      }
      }
      private:
      char *m_data; // 一指针成员
      };

    int main()
    {
    A a;
    A b(a); // 复制对象
    return 0;
    }
    `

  • 定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。
  • 什么时候使用:
    • 在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B通过使用析构函数等方式把内存释放了,这时A内的指针就是野指针(悬挂指针),运行错误。