关于c ++:为什么在数组动态分配内存时我们需要一个复制构造函数?

why do we need a copy constructor when an array is allocated memory dynamically?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is The Rule of Three?

1
2
3
4
5
6
7
Array(const Array &arraytoCopy)
:size(arraytoCopy.size)
{
    ptr=new int[size];
    for(i=0;i<size;i++)
        ptr[i]=arraytoCopy.ptr[i];
}

如果我不提供复制构造函数,将会发生什么。


当复制对象时,将有多个实例指向同一个动态分配的数组。目前还不清楚哪一个实例应该在销毁时负责取消分配。

如果该类应该拥有数组,那么它将负责取消分配其资源。在这种情况下,它应该有一个复制构造函数和赋值运算符来复制数组的内容,以及一个调用delete[]的析构函数。这就是所谓的三法则。在C++ 11中,它也应该有移动拷贝和移动赋值操作符。

如果该类不拥有数组,它可能不应该首先构造它。例如,它可以通过其构造函数接收指向外部分配的数组的指针。


由于类中拥有动态分配对象的原始指针,因此必须正确提供复制构造函数和复制分配运算符函数。

考虑下面的类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
class Array
{
public:
  Array()
  {
     ptr = new int[10];
  }
  ~Array(){
     delete [] ptr;
  }
private:
  int *ptr;  
};

当您实例化数组的两个对象时:

1
2
Array a1, a2;
a1 = a2;

现在,a1.ptr指向与p2.ptr相同的内存地址。在A1、A2的销毁过程中,PTR内存将被删除两次,这是未定义的行为。

使用std::vector int_collection_;是很好的解决方案,而不是使用原始指针。

1
2
3
4
5
6
7
8
9
10
11
class Array
    {
    public:
      Array()
      {          
      }
      ~Array(){            
      }
    private:
      std::vector<int> int_collection_;
    };


如果您的意图是不允许复制类实例,您可以将复制构造函数定义为私有的,并且不提供实现,以便编译器可以捕获这些情况,例如。

1
2
3
4
5
6
class Array
{
    ...
private:
    Array(const Array &arraytoCopy); // not implemented
};

在这种情况下,您不必担心上面描述的指针所有权问题。