I have trouble understanding why the following code doesn't construct and destruct the two objects I create the way I'd expect:
#include <iostream>
class MyClass {
int myVar;
public:
MyClass(int x) {
myVar = x;
std::cout << "constructing " << myVar << ", " << (long)this << std::endl;
}
~MyClass() {
std::cout << "destructing " << myVar << ", " << (long)this << std::endl;
}
};
int main(int argc, const char * argv[])
{
MyClass a = MyClass(1);
a = MyClass(2);
return 0;
}
I'd think that inside main I first create an object with the value 1, then create a new one with value 2. And each of the objects gets constructed and destructed, so that I'd expect to see the following output:
constructing 1, 3456
constructing 2, 6789
destructing 1, 3456
destructing 2, 6789
However, I get this:
constructing 1, 3456
constructing 2, 6789
destructing 2, 6789 <- note the "2"
destructing 2, 3456
Update: I've added output of the object's address (this) so that one can better see which object does what.
When I use "new MyClass" instead, I do not run into this weird effect.
What is causing this, and, understanding my goal, what is the right way to avoid similar mistakes in the future?
While this example looks harmless, I ran into crashes of my code because I had allocated other objects in the constructor and freed them in the destructor. This did lead to freeing the objects when the object was still in use.
Conclusion
Now that all my questions are answered, let me summarize:
- In the above example I'm using "myVar", which doesn't show even the issue that caused me to bring up this question. My apologies for that.
- The actual issue I had with the code is that I was not using a simple int var but an array that I created with "new" in the destructor, and freed with delete in the destructor. And with that, the array would get deleted twice, leading to incorrect data in my program.
- The fix is to not use a simple pointer to the array but a reference counting pointer, so that, when it gets copied by the assignment operator, it increases the refcount, thereby preventing premature release of it.
- In general, the effect I've shown here is nothing dangerous - it doesn't damage anything as I had gotten the impression. The dangerous part was that I didn't use ref counting ptrs.