Blocki's Revenge
Last night in class I was showing you that,
if you want value based semantics, that there are a number of
considerations to take into account when memory is allocated in a constructor.
I showed that an overload of the assignment
operator necessitates a check for self-reference. For example:
vec<int> A;
A = A;
might occur.
I then, full of self confidence, proclaimed that you do not have to consider self-reference in a copy constructor because:
vec<int> A;
vec<int> A(A);
can never occur. The compiler will catch the redefinition of A.
Then Jerimiah Blocki said, "I got it to do that." To which I said, "Impossible." And then he showed me the code:
vec<int> A;
vec<int> B(A);
B = *(new vec<int>(B));
And I said, "I never thought of that!"
This is an interesting conundrum. However, this morning I put together some example code that showed me what was going on:
vec.cpp.
What I did was to print out the address of B's p pointer prior to the call to new. I then, in the copy constructor, printed out this->p and &a.p. The result was:
In main: address of p in B 0012FF60
In copy constructor:
address of p in this CDCDCDCD
address of p in a 0012FF60
What this shows is that the new is creating an anonymous variable prior to assignment back to B. After the call to the copy constructor, there is a call to the assignment operator.
So, I was right all along, but just did not know it.