Normally in C++ with a pointer, if one were to create a dynamic object to pass into a function as a parameter, it would be done something like
Object *myObj = new Object;
someFunction(myObj);
delete myObj;
myObj = nullptr;
as opposed to
someFunction(new Object);
in order to not leak memory. Now suppose I am creating a garbage collected object; does the same rule still apply or would the garbage collector actually be able to delete a dynamically created object from memory created within the function call as shown below?
someFunction(gcnew Object);
someFunction(gcnew Object);
Sure, that's fine. The object won't survive for long, the next gen #0 collection is likely to destroy it if someFunction doesn't otherwise store the reference. You can declare a variable but that's pointless, it will be removed by the jitter optimizer at runtime and you'll end up with the exact same code.
Pretty important to keep in mind however that the delete
operator still exists in C++/CLI. But does something completely different than it does in native C++. It calls the IDisposable::Dispose() implementation method of a class. This provides "deterministic destruction", like it does in C++. Not quite the right word, it really is deterministic cleanup. The interface is implemented by any managed class that stores an "expensive" operating system resource, the kind you don't want to have hanging around until the garbage collector cleans it up.
Boilerplate example is the System::Drawing::Bitmap class. A very small class that is a wrapper for a big chunk of address space and (possibly) a file that is locked. You want to make sure to dispose it when you don't need it anymore. You could write such code like this:
void dosomething() {
Bitmap^ bmp = gcnew Bitmap("foo.png");
drawBitmap(bmp);
delete bmp;
}
But that isn't correct code, it isn't exception-safe. The delete operator call will be bypassed when drawBitmap throws an exception. Not the end of the world btw, this doesn't actually cause a leak since the GC ultimately will clean it up. Still, not pleasant, so the C++/CLI designers came up with an emulation for the native C++ RAII pattern, called "stack semantics" in C++/CLI:
void dosomething() {
Bitmap bmp("foo.png"); // NOTE: no ^ hat
drawBitmap(bmp);
} // <=== bmp is disposed here
This should look familiar to any C++ programmer :)