C++ 为什么我们需要删除复制赋值操作符中的指针

C++ 为什么我们需要删除复制赋值操作符中的指针,c++,assignment-operator,C++,Assignment Operator,我看过几个复制赋值运算符的示例,但不明白为什么需要删除复制赋值运算符中的指针。例如,如果我有下面的类 class MyClass { public: MyClass(int a) { x = new int(a); } MyClass& operator=(const MyClass& pMyClass) { *x = *(pMyClass.x); // ????????? /

我看过几个复制赋值运算符的示例,但不明白为什么需要删除复制赋值运算符中的指针。例如,如果我有下面的类

 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指向的对象,为什么我需要删除并再次创建它?。有人能举例说明此代码何时会导致内存泄漏吗?

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

当您将值从一个类实例复制到另一个类实例时,
*x=*(pMyClass.x)
没有问题。一般来说,删除一个对象(如果它不只是<代码> INT/COM>)可以防止新数据的使用,如果在<代码>运算符=< /C> >存储在<代码> X/COD>中的执行地址被发送到程序的其他部分。

< P>所以这是一个例子[从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
我们首先需要理解复制构造函数和复制赋值之间的区别。在第一种情况下(复制构造函数),我们创建一个全新的对象,而在第二种情况下(复制赋值,我们真正感兴趣的对象)我们已经有了一个现有的对象,我们只想将同一类型的另一个给定对象的内容复制到其中

鉴于我们已经有了一个现有的对象,我们首先需要清除它的内容,这样我们就能够从我们想要复制的对象中复制所需的内容


我希望这能回答您的问题。

您的“改进”“是完全有效的,但是
x
作为指针的第一点是什么?通常您会看到这样的情况,
x
指向一个数组,而旧数组的大小不适合新数据。然后你需要重新分配。存储分配的大小:
a
,然后在复制构造函数中,分配那么多并“复制”到新分配的内存中。除了显而易见的(在这个特定实现中使用指针毫无意义)有一个地方,您的建议不适用于不可复制分配,但可复制构造的类型。显然,
int
不属于这一类。