Let's put it this way: If what you claim would really be true, no C++/CLI could possibly run successfully. That's the reason you are so surprised. And how so often, the solution might be found in the code with which you are measuring this behaviour o rin the way you are interpreting the result.
So my recommendation is: Show us the destructor and copy-constructor code that prints those outputs from which you are deriving this interpretation.
In addition, the two cases you are showing are very different regarding the memory allocation scheme. The first example is about a reference class, the second about a value class. So what should happen in theory in your first example:
Thing^ MyManagedObject = gcnew Thing();
MyManagedObject->DoStuff();
MyManagedObject = gcnew Thing();
The second gcnew call assigns a new reference to
MyManagedObject
. Thereby, the reference to the first Thing object is lost. Nothing more. The GC will clean it up some time later; probably not right away but many hundred or thousand gcnew calls later. So I wouldn't be surprised if the destructor for the first
Thing
object wasn't called for a long time, perhaps even as late as the end of your program.
Now, perhaps with this new expectation in mind, you check your code of the Thing class and see if it would allow that interpretation.
Your second example is a totally different case:
Matrix Transform = OtherMatrix; Transform = OtherMatrix * SomethingElse;
Matrix is obviously a value class and its memory allocated on the stack, not the heap. The destructor for the
Transform
object should actually not be called here, instead I would expect the assignment operator to be executed. The compiler generates code for multiplying OtherMatrix with SomethingElse and the result is a temporary object of type Matrix that is allocated on the stack. This temporary object must be destroyed after assigning it to Transform. That is perhaps the destructor call you are observing. So the sequence I would expect is:
constructor call for creating the temporary object
operator*
assignment operator to transfer the result to Transform
destructor call to destroy the temporary object
Please review the printing code in the destructor and copy constructors and see if you are interpreting the results in the right way. Feel free to amend your question with your printing and test code that led you to this assumption and we will take a look at it. I am quite positive that after the dust settles everything will fall into place again.