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
}
If I understand correctly, the compiler will automatically create an assignment operator member function for Foo
. However, that just takes the value of ptr
in b
and puts it in a
. The memory allocated by a
originally seems lost. I could do a call a.~Foo();
before making the assignment, but I heard somewhere that you should rarely need to explicitly call a destructor. So let's say instead I write an assignment operator for Foo
that deletes the int
pointer of the left operand before assigning the r-value to the l-value. Like so:
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
this->ptr = other.ptr;
}
return *this;
}
But if I do that, then when Foo a
and Foo b
go out of scope, don't both their destructors run, deleting the same pointer twice (since they both point to the same thing now)?
Edit:
If I understand Anders K correctly, this is the proper way to do it:
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;
}
Now, a
cloned the int
that b
pointed to, and sets its own pointer to it. Perhaps in this situation, the delete
and new
were not necessary because it just involves int
s, but if the data member was not an int*
but rather a Bar*
or whatnot, a reallocation could be necessary.
Edit 2: The best solution appears to be the copy-and-swap idiom.