我见过几个复制赋值运算符的例子,无法理解为什么我们需要删除复制赋值运算符中的指针。例如,如果我有以下类
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指向的对象为什么我需要删除并再次创建它?当这段代码会导致内存泄漏时,有人可以举个例子吗?
答案 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
我们首先需要首先了解复制构造函数和复制分配之间的区别。在第一种情况(副本构造函数)中,我们创建了一个全新的对象,而在第二种情况(副本分配,我们真正感兴趣的对象)中,我们已经有一个现有对象,我们只想将另一个对象的内容复制到其中给定相同类型的对象。
鉴于我们已经有一个现有对象,我们首先需要清除其内容,以便我们能够从打算复制的对象中复制所需的内容。
我希望能回答您的问题。