I'm primarily a C++ programmer, and I've grown used to having class templates like std::unique_ptr
, std::shared_ptr
, etc for expressing ownership of my objects. Does Delphi have anything that is similar in its standard library? Are there any best-practices out there for expressing object ownership that I should be following as I write my code?
Edit: Since C++11 became standard, there are two lightweight helper classes, std::shared_ptr
and std::unique_ptr
.
If I create a variable of type std::shared_ptr<int>
, it represents a pointer to an int with shared ownership: under the hood is reference-counted, and when the ref-count reaches zero then the pointer is automatically freed. This type expresses a kind of "shared ownership", where many objects share the responsibility of destroying the resource when they are done with it.
In contrast, std::unique_ptr
expresses single ownership. When the unique_ptr goes out of scope, the resource is automatically freed. std::unique_ptr cannot be copied: there can be exactly one object owning this resource at a time, and there is exactly one object who is responsible to clean the object up.
Contrast these lightweight classes with a naked pointer to int, where it can represent either shared ownership, unique ownership, or it can just be a reference to an object somewhere else! The type tells you nothing.
My question is: as Delphi supports holding references to objects, are there any mechanisms for explicitly stating "I am the sole owner of this object, when I'm done with it, I will free it", vs "I am merely keeping a reference to this object around for the purpose of interacting with it, but somebody else will clean it up" vs "I share this object with many other objects, and whoever has it last gets to clean it up."
I know that Collections.Generics has different collections such as TList
vs TObjectList
, where TObjectList will free the members stored within it, but TList won't. You can say that TObjectList "owns" it's elements, whereas TList doesn't. This is the essence of my question, really. When designing my own classes, are there ways of directly expressing these kinds of ownership issues within the language? Or are there any best practices/naming conventions that are common amongst developers?
I am not aware of any language constructs that can help, nor of any "standard naming conventions".
However, long ago, I have adopted the following naming convention to make it easier to check whether classes clean up behind themselves properly:
Very crude, but it works, and has helped a lot when going through code you haven't seen in a while to prevent those "Wait, shouldn't that reference be freed or nilled?" searches.