struct Foo
{
Foo(int i)
{
ptr = new int(i);
}
~Foo()
{
delete ptr;
}
int* ptr;
};
int main()
{
{
Foo a(8);
Foo b(7);
a = b;
}
//Do other stuff
}
如果我理解正确,编译器会自动为Foo
. 但是,这只是取ptr
in的值b
并将其放入a
。最初分配的内存a
似乎丢失了。我可以a.~Foo();
在分配之前打个电话,但我听说你应该很少需要显式调用析构函数。因此,假设我编写了一个赋值运算符,用于在将 r 值分配给 l 值之前Foo
删除int
左操作数的指针。像这样:
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
this->ptr = other.ptr;
}
return *this;
}
但是如果我这样做,那么当Foo a
和Foo b
超出范围时,它们的析构函数不会运行,两次删除相同的指针(因为它们现在都指向同一个东西)?
编辑:
如果我正确理解 Anders K,这是正确的方法:
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
//Clones the int
this->ptr = new int(*other.ptr);
}
return *this;
}
现在,a
克隆指向的int
那个,并设置它自己的指针。b
也许在这种情况下,delete
andnew
不是必需的,因为它只涉及int
s,但如果数据成员不是 anint*
而是 aBar*
或诸如此类,则可能需要重新分配。
编辑 2: 最好的解决方案似乎是copy-and-swap idiom。