动态数组...复制构造函数,析构函数,重载赋值运算符

时间:2009-02-24 06:00:01

标签: c++ constructor

我正在读我的期中考试。有一个关于动态设置数组的问题,可能还有复制构造函数,析构函数和重载赋值运算符。你可以验证我是否正确。另外我不明白赋值运算符的重载是什么意思。你能帮我解决这个问题吗?

class A
{
int* myArray;   //basically I created a pointer called myArray, 
A()             //are my copy constructors correct? A(), and A(int size)?
{
    myArray = 0;
}
A(int size)
{
    myArray = new int[size];
}
~A()             // I think my destructor is correct
{
    delete [] myArray;
}

请检查我的代码吗?另外我如何重载赋值运算符?

提前致谢。

5 个答案:

答案 0 :(得分:7)

您已正确定义了2个重载构造函数和析构函数。

但是,您尚未正确定义显式复制构造函数

通常,编译器会为您生成一个,这称为隐式复制构造函数

在您的特定情况下,自动生成的隐式复制构造函数的问题在于它只会执行 myArray 的浅层副本,它会共享相同的指针值但尚未分配自己的myArray的内存部分。

这意味着如果您删除原始对象中的myArray,它将影响很可能不是您想要的副本。

定义这样的显式复制构造函数会有所帮助:

A(const A& copy)
  : _size(copy.size), myArray(new int[copy.size]) 
{
    // #include <algorithm> for std::copy
    std::copy(copy.data, copy.data + copy.size, data);
}

(来源:从Wikipedia复制)

如果像这样定义复制构造函数,则不需要重载赋值运算符。如果您创建一个新对象,并将其分配给您创建的第一个对象,您将成功创建第一个对象的独立副本。

修改:来自this article

  

复制赋值运算符不同   从它的复制构造函数   必须清理数据成员   任务的目标(并且正确   处理自我分配)而   复制构造函数将值赋给   未初始化的数据成员。

答案 1 :(得分:6)

复制构造函数用于基于另一个相同类型的实例创建对象。你没有这样的。您可以使用以下代码定义它:

A(const A &other)
{
   myArray = new int[other._size];
   _size = other._size;
   memcpy(myArray, other.myArray, sizeof(int) * _size);
}

您应该更改您的类,因此它将存储数组的_size,您还需要将构造函数和析构函数的可见性更改为public。

重载的赋值运算符应如下所示:

const A &operator=(const A &other)
{
   if(this == &other) return *this; // handling of self assignment, thanks for your advice, arul.
   delete[] myArray; // freeing previously used memory
   myArray = new int[other._size];
   _size = other._size;
   memcpy(myArray, other.myArray, sizeof(int) * _size);
   return *this;
}

您还可以在此赋值运算符中添加数组大小相等的检查,这样您就可以重用动态数组而无需不必要的内存重新分配。

答案 2 :(得分:4)

在处理对象复制和动态内存分配时,最好使用交换帮助函数

A(const A& other)
    : myArray(0)
    , _size(0)
{
   if(this != &other) {
      A my_tmp_a(other._size);
      std::copy(&other[0], &other[other._size], &my_tmp_a[0]);
      swap(my_tmp_a);
   }
}

const A& operator=(const A& other)
{
   if(this == &other) return *this;
   A my_tmp_a(other._size);
   std::copy(&other[0], &other[other._size], &my_tmp_a[0]); 
   swap(my_tmp_a);       
   return *this;
}

void swap(const A& other) {
   int* my_tmp_array = this.myArray;
   this.myArray = other.myArray;
   other.myArray = my_tmp_array;
   int my_tmp_size = this._size;
   this._size = other._size;
   other._size = my_tmp_size;
}

答案 3 :(得分:1)

如果要定义其中一个函数,请确保定义三个函数。它被称为全部或无规则 他们是: 1)复制构造函数。 2)赋值运算符。 3)析构函数。

答案 4 :(得分:0)

部分答案:重载函数涉及创建该函数的不同版本,这些版本接受不同数量或种类的参数。因此,重载赋值运算符将涉及为赋值运算符创建多个函数,这些函数允许您将各种类型的对象分配给A类型的变量。