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. 但是,这只是取ptrin的值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也许在这种情况下,deleteandnew不是必需的,因为它只涉及ints,但如果数据成员不是 anint*而是 aBar*或诸如此类,则可能需要重新分配。
编辑 2: 最好的解决方案似乎是copy-and-swap idiom。