【问题标题】:Why do we need to delete pointers inside copy assignment operator为什么我们需要删除复制赋值运算符中的指针
【发布时间】:2015-05-01 10:07:44
【问题描述】:

我看过几个复制赋值运算符的例子,不明白为什么我们需要删除复制赋值运算符中的指针。例如,如果我有以下课程

 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 首先是一个指针有什么意义呢?通常你会看到x 指向一个数组,而旧数组的大小不适合新数据。然后你需要重新分配。
  • 存储分配的大小:a 然后在复制构造函数中,分配那么多并“复制”到新分配的内存。
  • 除了显而易见的(对这个特定的实现使用指针毫无意义)之外,你提出的一个地方 not 工作将是一个 not 可复制分配,但 可复制构造的。显然int 不属于这一类。

标签: c++ assignment-operator


【解决方案1】:

所以这是一个用户定义向量类的复制分配示例 [摘自 Bjarne Stroustrup 的“C++ 之旅(第 2 版)”:

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-30
        • 1970-01-01
        • 1970-01-01
        • 2019-01-01
        • 1970-01-01
        • 2011-04-19
        • 2011-07-26
        • 2018-09-14
        相关资源
        最近更新 更多