【问题标题】:Is this copy constructor doing a deep copy or shallow copy?这个拷贝构造函数是做深拷贝还是浅拷贝?
【发布时间】:2013-03-09 18:25:46
【问题描述】:

我有一个名为Directory 的类,其中包含某些成员,后跟一个复制构造函数。

class  Directory{

private:
    char * Name;                
    int Telephone_Number;   
    char * Address;             
public:
    Directory (Directory & b)    
    {
        Name = new char [10];   //Just assume that the name will not be greater than                                    //10 characters
        Address = new char [30]; //Same here 
        strcpy (Name, b.Name);
        Telephone_Number = b.Telephone_Number;
        strcpy (Address, b.Address);
    }
};

我想知道我的复制构造函数是执行深复制还是浅复制。我知道这是深度复制AddressName 因为正在为它们分配新内存,但是Telephone_Number 呢?

我的代码是在做浅拷贝还是深拷贝?任何人都可以向我解释一般的复制构造函数吗?

【问题讨论】:

  • 没有“拷贝拷贝构造函数”这样的东西
  • 输入错误,抱歉。
  • 但是问题变得更加奇怪了 :) “一般解释,具体解释”是什么意思?
  • 在分配 new 内存之前,不要忘记delete NameAddress
  • @MM。或者更确切地说,不要忘记将那些 char* 转换为 std::string 并删除 new 运算符!

标签: c++ constructor copy-constructor


【解决方案1】:
Name = new char [10];
Address = new char [30]; //Same here 
strcpy (Name, b.Name);
strcpy (Address, b.Address);

名称和地址将只是实际的内存地址 细绳。因此,当我们复制 'Name'/'Address' 时,我们必须复制 'Name'/'Address' 指向的实际内容。如果我们只进行如下浅层复制,

b.Name = Name; 
b.Address = Address;

我们只是指向由某人创建的数据,这些数据也可能被该人删除。如果有人删除实际内容,我们将指向该内容,假设其可用。现在指针悬空(无指向) . 这就是我们使用复制构造函数的原因。

Telephone_Number = b.Telephone_Number;

'Telephone_Number' 保存的是实际值。所以浅拷贝足以复制值

名称/地址会有内存地址,浅拷贝会复制 只是实际值的内存地址。

Telephone_Number 将有一个整数值,浅拷贝将复制 那个整数值

所以复制构造函数是“完美”的深度复制。

【讨论】:

    【解决方案2】:

    很明显,这是对地址和名称的深度复制,因为正在为它们分配新的内存,但是 Telephone_Number 呢?

    一个int,就像电话号码一样,总是被深度复制的。

    我当前的代码是在做浅拷贝还是深拷贝?

    谁能概括地解释复制构造函数并专门向我解释复制构造函数?

    编译器合成的复制构造函数只会生成成员 成员副本,即复制指针值,而不是其内容。编译器合成的复制构造函数总是很浅的。每当需要深度复制时,课程作者都必须编写它(就像您所做的那样)。

    另外,应该更正复制构造函数的签名以通过 const 引用的原始对象(此处为b)以防止其被意外修改:

    Directory (Directory const & b) 
                         ^^^^^^
    

    【讨论】:

      【解决方案3】:

      正如其他人所说,这是一个深拷贝。

      一般而言,当您使用复制构造函数时,其想法是获取深层副本。这意味着副本不与原始共享数据。

      那么让我们看看以下内容:

      Directory B = new Directory(A);
      A->DoSomething();
      B->DoSomething();
      

      当我阅读上面的代码时,我预计A->DoSomething() 只会影响A 中的数据。 B->DoSomething() 也是如此。

      但是,深层复制规则可能存在例外情况。可能数据量大,复制可能效率不高:

      class LargeData {
          int* PointerToLargeArray;
      }
      

      在上述情况下,您可以通过复制指针而不是数据来实现复制构造函数:

      LargeData(LargeData& b)
      {
          PointerToLargeArray = b->PointerToLargeArray;
      }
      

      【讨论】:

      • @TheAbster - 如果您觉得这个答案有用,请点赞。
      【解决方案4】:

      Telephone_Number 在类中被声明为int 并按值复制(没有引用或指针或任何东西),因此此构造函数正在执行深度复制

      Wikipedia 或任何优秀的 C++ 书籍中都有很多关于复制构造函数的信息,您应该先阅读类似的内容,然后看看您是否还有其他具体问题。

      这可能值得花时间阅读,有一些重要的规则可以控制在初始化和分配对象时如何使用复制构造函数,您应该了解这些规则。

      【讨论】:

      • 谢谢。我会复习的。
      【解决方案5】:

      这是一个深拷贝。整数总是被复制。

      【讨论】:

        【解决方案6】:

        这是一个深拷贝。您的 int 按值复制,而您没有复制引用或指针。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-30
          • 1970-01-01
          • 2011-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多