Hi, in my quest to learn C++ using Bruce Eckels book, a chapter is dedicated to the copy constructor. While experimenting with the situations presented I triggered some unexpected behaviour I can't explain. I hope one of you can explain why the destructor is triggered twice in the following situation:
Consider the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#include <iostream>
#include <fstream>
using namespace std;
#define out cout
//ofstream out("HowMany.out");
class HowMany {
static int objectCount;
public:
HowMany() { objectCount++; }
static void print(const string& msg = "") {
if(msg.size() != 0) out << msg << ": ";
out << "objectCount = "
<< objectCount << endl;
}
~HowMany() {
objectCount--;
print("~HowMany()");
}
};
int HowMany::objectCount = 0;
// Pass and return BY VALUE:
HowMany f(HowMany x) {
x.print("x argument inside f()");
return x;
}
int main(void) {
HowMany h;
HowMany::print("after construction of h"); HowMany h2 = f(h);
//h2 = f(h);
HowMany::print("after call to f()");
HowMany::print("end of main");
return 0; // h & h2 are destroyed
}
|
output:
after construction of h: objectCount = 1
x argument inside f(): objectCount = 1
~HowMany(): objectCount = 0
after call to f(): objectCount = 0
end of main: objectCount = 0
~HowMany(): objectCount = -1
~HowMany(): objectCount = -2 |
Ok, according to Bruce this is because C++ is performing a bitcopy rather than calling the constructor. So the first destructor call would apply to "x inside f".
At the end of main "h & h2" are destroyed. So we see 3 destructor calls in this piece of code, and since the constructor was skipped in two occasions the count is now negative: -2.
So far so good.
But now in my experimentation I added one line of code to main, which now looks like this:
1 2 3 4 5 6 7 8 9 10
|
int main(void) {
HowMany h;
HowMany::print("after construction of h"); HowMany h2 = f(h);
h2 = f(h);
HowMany::print("after call to f()");
HowMany::print("end of main");
return 0; // h & h2 are destroyed
}
|
I expected this would cause another 'x in f' to be bitcopied and destructed, so in total 4 destructor calls. Yet, somehow it calls the destructor twice more in this situation. it's been hurting my brain for a the past hour, why does it happen, what is it trying to destroy?
Adding this line several times will result in 2 more destructor calls for each line.
In summary:
Why does it call the destructor on "x in f" only once at initialization of h2, but why does it call the destructor twice if h2 already exists?