为什么我们需要删除复制赋值运算符中的指针

时间:2015-02-28 20:14:29

标签: c++ assignment-operator

我见过几个复制赋值运算符的例子,无法理解为什么我们需要删除复制赋值运算符中的指针。例如,如果我有以下类

 class MyClass
 {
  public:
    MyClass(int a)
    {
      x = new int(a);
    }
    MyClass& operator=(const MyClass& pMyClass)
    {
       *x = *(pMyClass.x);

       // ?????????
       // delete x;
       // x = new int(*(pMyClass.x));
    }
    ~MyClass()
    {
       delete x;
    }
  private:
    int* x;
 }

* x = *(pMyClass.x)行有什么问题?我只是复制pMyClass.x指向的对象为什么我需要删除并再次创建它?当这段代码会导致内存泄漏时,有人可以举个例子吗?

3 个答案:

答案 0 :(得分:0)

这是一个有效的代码。但是,如果不是指向单个对象的指针,而是指向数组的第一个元素,并且数组可能具有不同的大小,那么您需要删除用新大小重新分配它的数组。

答案 1 :(得分:0)

将值从一个类实例复制到另一个类时,*x = *(pMyClass.x)没有错误。我认为,一般来说,删除一个对象(如果它不仅仅是int)可以阻止在operator=存储在x中的{{1}}执行地址发送到某些对象之前使用新数据程序的其他部分。

答案 2 :(得分:0)

这是一个示例(从Bjarne Stroustrup的“ C ++之旅(第二版)中摘录)”中的一个用户定义的矢量类的副本分配:

Vector& Vector::operator=(const Vector& a) // copy assignment
{
double∗ p = new double[a.sz];
for (int i=0; i!=a.sz; ++i)
p[i] = a.elem[i];
delete[] elem; // delete old elements
elem = p; // here elem is the vector's data holding member array
sz = a.sz;
return ∗this;
}

要了解为什么在第6行中执行删除操作:

delete[] elem; // delete old elements

我们首先需要首先了解复制构造函数和复制分配之间的区别。在第一种情况(副本构造函数)中,我们创建了一个全新的对象,而在第二种情况(副本分配,我们真正感兴趣的对象)中,我们已经有一个现有对象,我们只想将另一个对象的内容复制到其中给定相同类型的对象。

鉴于我们已经有一个现有对象,我们首先需要清除其内容,以便我们能够从打算复制的对象中复制所需的内容。

我希望能回答您的问题。