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.