How do I tell if I'm leaking COM objects? - c++

I'm writing some code that makes (relatively simple) use of COM, calling AddRef() on some objects and Release()ing them later. Other than just checking the code really thoroughly, is there a way I can check to see if I'm leaking COM objects everywhere?
(I can't use reference counted IBlahBlahPtrs because I need to pass the objects to a set of APIs who don't know what a COM is, and so don't understand the whole "reference counting pointers" thingy - they pass the pointer around like a token.)
Thanks!

It is no different from checking for leaks in any C or C++ code. Use <crtdbg.h> to detect leaks, the MSDN library article is here. You'll get a leak report for the class factory if there were not enough IUnknown::Release() calls.
Reference counting interface pointers is a hard COM requirement, you cannot just shrug it off. If the client code doesn't do it then you'll have to take care of it yourself before you pass a pointer to that code. Knowing when the pointer is no longer in use is of course the trickier issue.

If you use the CrtDebug DEBUG_NEW to allocate your objects, you'll get an automatic dump of all leaked objects at exit time (basically, all memory that is not freed), along with the file name and line where the memory was allocated.

Based on our conversation in comments, I'd say you could do the following:
Use smart pointers (i.e., IBlahBlahPtr) to create and manage COM objects in your own code.
Maintain a collection of smart pointers representing your caller's references to the pointers that you've passed upwards. Every time you hand a new COM pointer over to your caller, put its smart pointer in the collection.
If your caller relinquishes a COM pointer somehow (by, say, passing you the COM pointer token in some kind of "release" function), then look up its smart pointer in the collection and remove it. If that smart pointer (representing the caller's now-defunct reference to the object) is the only remaining holder of a reference count on the object, then destruction will occur as desired.
If your caller passes you a COM pointer in a non-relinquishing way, you can wrap a new smart pointer object around the raw pointer value for the duration of the call, just so that your use of smart pointers within your own code is consistent. It's fine for multiple smart pointers to refer to the same COM object.

Various tools will check for you. BoundsChecker does. I think, but am not 100% sure, that AppVerifier does (it has the added benefit of being free).

Related

Do I have to call a release function using a ComPtr?

I'm using a smart pointer or a ComPtr. I'm using it with my directX application and I haven't seen other people call the release function in their code using the ComPtr. So does the smart pointer release the data that the smart pointer is referring to or do I need to do it manually? I don't know if this makes since so tell me if it doesn't and I will respond with better detail.
You should never call AddRef or Release on a ComPtr, and by default you can't. You have to use hacky patterns like comPtr.Get()->Release to do it, and you are mostly like going to cause problems.
The purpose of Microsoft::WRL::ComPtr is to make COM pointer cleanup automatic, both in normal code and when handling C++ exceptions. Making a copy of a ComPtr to another ComPtr automatically increase the ref-count, and each time a ComPtr variable goes out of scope it automatically decreases the ref-count. This greatly simplifies error-handling and cleanup which is why the code you are looking at isn't awash in calls to Release.
There are special methods Attach and Detach for 'transferring ownership' so that the ref-count is not changed, but they are for special use cases. There are also some tricks you can do with Swap as well that are very useful for robust coding.
If you want to explicitly 'release' a ComPtr variable, you can assign null to it or better yet use Reset.
Like with all smart-pointers you should think about the lifetime of your pointer to decide how to use it. If a function or class is going to 'own' the object pointed to, then use of a smart-pointer is the right way to do it. If the function is just going to work with the object and then return without any change in lifetime, the function should take a raw pointer instead with you using the Get method on the ComPtr when calling it. Otherwise your program wastes a lot of time needlessly increasing and decreasing the ref-count when the ownership of the object was not actually in question.
Another option is to pass the smart-pointer parameter as const ComPtr& which avoids the ref-count cycling, but it has the side-effect of forcing the caller to use ComPtr when the raw pointer is more agnostic to the caller's object lifetime policy and therefore more flexible.
I've got a write-up of how to use ComPtr on the DirectX Tool Kit wiki. You can also see MSDN.
For non-COM objects, std::unique_ptr is a great option. You can also use std::shared_ptr and std::weak_ptr but there are a lot of performance implications and edge-cases to worry about in the shared case, so sticking to ComPtr for COM and std::unique_ptr for heap-allocated objects with a single-owner is best practice.
You should not normally need to call AddRef or Release through the smart pointer - the entire point of ComPtr is that it calls those for you.
You might still need to call them if you're converting a smart pointer to a "manually managed" (normal) pointer.

Will using shared_ptr for returning pointers from a method always save me from memory leaks?

I'm a c++ newbie, my code currently new's up on the heap in several places without calling delete. I know I need to do something about this.
My typical usage is where I new up a class instance in another classes member method then the method returns the pointer to the object.
If i change the return types from MyType* to std::tr1::shared_ptr will this fix my code to not leak memory?
Thanks a lot.
Edit:
Also likewise, I currently store new'ed up objects as MyType* as a value in a std:map. This map is a private member to a class instance. If I simply change this to std::tr1::shared_ptr will this clear up these when it's owner (class) falls out of scope?
Thanks again
It's a reasonable band-aid, sure.
A shared pointer is a reference-counted pointer. So as long as one or more shared_ptrs exist pointing to an object, that object will be kept alive. The problem occurs if you have circular references. Then the reference count will never reach 0, and the object(s) will never be deleted.
So shared_ptr * still* require you to understand what you're doing and think about object ownership, as you always have to do in C++. But it simplifies some otherwise complex scenarios, where determining ownership is hard.
But the real fix to your problem is to:
minimize how much you allocate with new. Can the object instead be stored on the stack? Can the object be rewritten as a RAII class, so that a small wrapper object is allocated on the stack (or elsewhere with automatic storage duration), and which, through its constructors and destructors, manages a heap-allocated memory resource? Then, as long as that object exists, its allocated memory will be preserved, and once it is destroyed, it will delete its allocated memory.
when you allocate objects with new, put them in one of the smart pointer classes. shared_ptr is popular because it is the one that comes closest to looking like a garbage collector, but it isn't, and if you treat it as one and use it as an excuse to not think about memory management, then it won't work. Understand all the smart pointer classes (scoped_ptr and auto_ptr in C++03, or unique_ptr replacing both in C++11, shared_ptr and weak_ptr), and use the one that best fits your scenario.
think about ownership. Any time you allocate memory, you need to determine an owner, whose lifetime will control the lifetime of the memory allocation. Think about how long a lifetime your allocation needs, and have another object (whose lifetime is automatically managed, probably because it is on the stack) delete your memory when its destructor is called.
There's no quick and easy fix. The way to handle memory management in C++ is to avoid memory management. Delegate it out to your objects. If you're calling delete in your own code, you're doing it wrong. Often, you don't even need new, but if you do, assign ownership to a smart pointer immediately, and let that call delete for you.
As a rule of thumb, unless you're a library writer, you shouldn't write either new or delete. You should virtually never use raw pointers, and only when it is absolutely necessary, use smart pointers. Let your classes do the heavy lifting. Don't be afraid to put them on the stack, pass them by value, and let them handle their resources internally.
If you are new to C++ there are a few points with pointer management you need to understand and accept, regardless of whether you're using shared_ptr or not.
It is more than likely in your use of C++ you will need to use new and assign its return pointer to a class pointer that you have declared. I believe it is advisable to take the time to understand what is going on there, even if you write a small test program and watch the constructor execute in the debugger.
If you use classes like std::string, its constructors and destructor will do string pointer management for you, but I believe it is a good idea to understand what is going on behind the scenes in that class, if nothing more than reading the documentation.
As another example, you cannot use some classes, without a lot of detailed reading of the API, or you'll get problems. I once worked at company that used a commercial class package years ago. Someone had written a multi-threaded program using this package's thread pool class.
The documentation clearly said you can't just exit with outstanding threads. Yet I saw where the author of the program did not bother to synch up and shutdown all threads on exit, and wound up throwing exceptions, when their program exited. And this was on a commercial financial product.
My suggestion is don't look to get saved from performing pointer management. There are std classes like string that can reduce your headaches, but nothing will prevent problems other than your own diligence and testing.
As long as you understand how tr1 shared pointers work, yes.
Look at Boost C++ shared_ptr<> also - it might be more what you want.

Usage of Smart Pointers as a Programming Standard?

More and more I hear, that I should use smart pointers instead of naked pointers, despite I have effective memory leak system implemented.
What is the correct programming approach on using smart pointers please? Should they really be used, even if I check memory leaks on allocated memory blocks? Is it still up to me? If I do not use them, can this be considered as programming weakness?
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
You should use RAII to handle all resource allocations.
Smart pointers are just one common special case of that rule.
And smart pointers are more than just shared_ptr. There are different smart pointers with different ownership semantics. Use the one that suits your needs. (The main ones are scoped_ptr, shared_ptr, weak_ptr and auto_ptr/unique_ptr (prefer the latter where available). Depending on your compiler, they may be available in the standard library, as part of TR1, or not at all, in which case you can get them through the Boost libraries.
And yes, you should absolutely use these. It costs you nothing (if done correctly, you lose zero performance), and it gains you a lot (memory and other resources are automatically freed, and you don't have to remember to handle it manually, and your code using the resource gets shorter and more concise)
Note that not every pointer usage represents some kind of resource ownership, and so not all raw pointer usage is wrong. If you simply need to point to an object owned by someone else, a raw pointer is perfectly suitable. But if you own the object, then you should take proper ownership of it, either by giving the class itself RAII semantics, or by wrapping it in a smart pointer.
You can't just blindly substitute std::auto_ptr for every raw pointer. In particular, auto_ptr transfers ownership on assignment, which is great for some purposes but definitely not for others.
There is a real reason there are several varieties of smart pointers (e.g., shared_ptr, weak_ptr, auto_ptr/unique_ptr, etc.) Each fulfills a different purpose. One major weakness of a "raw" pointer is that it has so many different uses (and has that versatility largely because it does little or nothing to assist in any one purpose). Smart pointers tend to be more specialized, which means they can be more intelligent about doing one thing well, but also means you have to pick the right one for the job or it'll end up dong the wrong things entirely.
Smart pointers allows to define automatically the life-time of objects it refers to. That's the main thing to understand.
So, no, you shouldn't use smart pointers everywhere, only when you want to automate life-time of your objects instead of having, for example, an object managing those objects inside from birth to death. It's like any tool : it solves specific kind of problems, not all problems.
For each object, you should think about the life cycle it will go through, then choose one of the simplest correct and efficient solution. Sometimes it will be shared_ptr because you want the object to be used by several components and to be automatically destroyed once not used anymore. Sometimes you need the object only in the current scope/parent-object, so scoped_ptr might be more appropriate. Sometimes you need only one owner of the instance, so unique_ptr is appropriate. Maybe you'll find cases where you know an algorithm that might define/automate the lifetime of an object, so you'll write your own smart pointer for it.
For example of opposite case, using pools forbids you to use smart_ptr. Naked pointers might be a more welcome simple and efficient solution in this particular (but common in embedded software) case.
See this answer (from me) for more explainations : https://softwareengineering.stackexchange.com/questions/57581/in-c-is-it-a-reflection-of-poor-software-design-if-objects-are-deleted-manuall/57611#57611
Should they really be used, even if I check memory leaks on allocated memory blocks?
YES
The whole purpose of smart pointers is, it help you implement RAII(SBRM), which basically lets the resource itself take the responsibility of its deallocation and the resource doesn't have to rely on you explicitly remembering to deallocate it.
If I do not use them, can this be considered as programming weakness?
NO,
It is not a weakness but a inconvenience or unnecessary hassle to explicitly manage the resources by yourself if you are not using Smart pointers(RAII). The purpose of smart pointers to implement RAII is to provide efficient and hassle free way of handling resources and you would just not be making use of it if you are not using it. It is highly recommended to use it purely for the numerous advantages it provides.
If the smart pointers(ex: std::auto_ptr)are strongly recommended, should I use them instead of every naked pointer?
YES
You should use smart pointers wherever possible because simply there is no drawback of using them and just numerous advantages to use them.
Don't use auto_ptr though because it is already deprecated!! There are various other smart pointers available that you can use depending on the requirement. You can refer the link above to know more about them.
It's a tricky question, and the fact that there is currently a mode to
use smart pointers everywhere doesn't make things any easier. Smart
pointers can help in certain situations, but you certainly can't just
use them everywhere, without thinking. There are many different types
of smart pointers, and you have to think about which one is appropriate
in every case; and even then, most of your pointers (at least in typical
applications in the domains I've worked in) should be raw pointers.
Regardless of the approach, several points are worth mentionning:
Don't use dynamic allocation unless you have to. In many
applications, the only things that need to be allocated dynamically
are objects with specific lifetimes, determined by the application
logic. Don't use dynamic allocation for objects with value semantics.
With regards to entity object, those which model something in the
application domain: these should be created and destructed according
to the program logic. Irregardless of whether there are pointers to
them or not. If their destruction causes a problem, then you have an
error in your program logic somewhere (not handling an event correctly,
etc.), and using smart pointers won't change anything.
A typical example of an entity object might be client connection in a
server, is created when the client connects, and destructed when the
client disconnects. In many such cases, the most appropriate management
will be a delete this, since it is the connection which will receive
the disconnection event. (Objects which hold pointers to such an object
will have to register with it, in order to be informed of its
destruction. But such pointers are purely for navigation, and shouldn't
be smart pointers.)
What you'll usually find when people try to use smart pointers
everywhere is that memory leaks; typical reference counters don't
handle cycles, and of course, typical applications are full of cycles: a
Connection will point to the Client which is connected to it, and
the Client will contain a list of Connection where it is connected.
And if the smart pointer is boost::shared_ptr, there's also a definite
risk of dangling pointers: it's far to easy to create two
boost::shared_ptr to the same address (which results in two counters
for the references).
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
In my opinion, yes, you should it for every pointer that you own.
Here are my ideas on resource management in C++ (feel free to disagree):
Good resource management requires thinking in terms of ownership.
Resources should be managed managed by objects (RAII).
Usually single ownership is preferred over shared ownership.
Ideally the creator is also the owner of the object. (However, there are situations where ownership transfer is in order.)
This leads to the following practices:
Make boost::scoped_ptr the default choice for local and member variables. Do keep in mind that using scoped_ptr for member variables will make your class non-copyable. If you don't want this see next point.
Use boost::shared_ptr for containers or to enable shared ownership:
// Container of MyClass* pointers:
typedef boost::shared_ptr<MyClass> MyClassPtr;
std::vector<MyClassPtr> vec;
The std::auto_ptr (C++03) can be used for ownership transfer. For example as the return value of factory or clone methods:
// Factory method returns auto_ptr
std::auto_ptr<Button> button = Button::Create(...);
// Clone method returns auto_ptr
std::auto_ptr<MyClass> copy = obj->clone();
// Use release() to transfer the ownership to a scoped_ptr or shared_ptr
boost::scoped_ptr<MyClass> copy(obj->clone().release());
If you need to store a pointer that you don't own then you can use a raw pointer:
this->parent = inParentObject;
In certain situations a boost::weak_pointer is required. See the documentation for more information.
In general you should prefer smart pointers, but there are a couple of exceptions.
If you need to recast a pointer, for example to provide a const version, that becomes nearly impossible with smart pointers.
Smart pointers are used to control object lifetime. Often when you are passing a pointer to a function, the function will not affect the lifetime; the function does not try to delete the object, and it does not store a copy of the pointer. The calling code cannot delete the object until the function returns. In that case a dumb pointer is perfectly acceptable.
Yes. Assuming you have C++0x available to you, use unique_ptr or shared_ptr (as appropriate) to wrap all the raw pointers you new up. With the help of make_shared, shared_ptr is highly performant. If you don't need reference counting then unique_ptr will get you better perf. Both of them behave properly in collections and other circumstances where auto_ptr was a dumb pointer.
Using smart pointers (shared_ptr or otherwise) EVERYWHERE is a bad idea. It's good to use shared_ptr to manage the lifetime of objects/resources but it's not a good idea to pass them as parameters to functions etc. That increases the likelihood of circular references and other extremely hard to track bugs (Personal experience: Try figuring out who should not be holding onto a resource in 2 millions lines of code if every function invocation changes the reference count - you will end up thinking the guys who do this kind of thing are m***ns). Better to pass a raw pointer or a reference.
The situation is even worse when combined with lazy instantiation.
I would suggest that developers should know the lifecycle of the objects they write and use shared_ptr to control that (RAII) but not extend shared_ptr use beyond that.

Getting started with smart pointers in C++

I have a C++ application which makes extensively use of pointers to maintain quite complex data structures. The application performs mathematical simulations on huge data sets (which could take several GB of memory), and is compiled using Microsoft's Visual Studio 2010.
I am now reworking an important part of the application. To reduce errors (dangling pointers, memory leaks, ...) I would want to start using smart pointers. Sacrificing memory or performance is acceptible as long as it is limited.
In practice most of the classes are maintained in big pools (one pool per class) and although the classes can refer to each other, you could consider the pool as owner of all the instances of that class. However, if the pool decides to delete an instance, I don't want any of the other classes that still refers to the deleted instance to have a dangling pointer.
In another part I keep a collection of pointers to instances that are delivered by other modules in the application. In practice the other modules maintain ownership of the passed instance, but in some cases, modules don't want to take care of the ownership and just want to pass the instance to the collection, telling it "it's yours now, manage it".
What is the best way to start introducing smart pointers? Just replacing pointers [at random] with smart pointers doesn't seem a correct way, and probably doesn't deliver all the (or any of the) advantages of smart pointers. But what is a better method?
Which types of smart pointers should I further investigate? I sometimes use std::auto_ptr for the deallocation of locally allocated memory, but this seems to be deprected in C++0x. Is std::unique_ptr a better alternative? Or should I go straight to shared pointers or other types of smart pointers?
The question Replacing existing raw pointers with smart pointers seems similar but instead of asking how easy it is, I am asking what the best approach would be, and which kind of smart pointers are suited best.
Thanks in advance for your ideas and suggestions.
I recommend using unique_ptr when possible (this may require some program analysis) and shared_ptr when this is impossible. When in doubt, use a shared_ptr to maximize safety: when handing off control to a container, the reference count will simply go to two and then back to one and the container will eventually delete the associated object automatically. When performance becomes an issue, consider using boost::intrusive_ptr.
Here are the 3 varieties found in the new C++11 standard (unique_ptr replaces auto_ptr)
http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr
http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr
http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr
You can read the text for each pointer and there is an explanation of when to use which in there. For local memory management unique_ptr is the choice. It is non-copyable but movable so as you move it around the receiver takes ownership of it.
Shared_ptr is used if you want to share an object instance around with no one really owning the object and to make sure it doesn't get deleted while someone still has a reference to it. Once the last user of an object destroys the shared_ptr container, the contained object will be deleted.
weak_ptr is used in conjunction with shared_ptr. It enables one to "lock" to see if the reference shared_ptr object still exists before trying to access the internal object.

smart pointers + "this" considered harmful?

In a C++ project that uses smart pointers, such as boost::shared_ptr, what is a good design philosophy regarding use of "this"?
Consider that:
It's dangerous to store the raw pointer contained in any smart pointer for later use. You've given up control of object deletion and trust the smart pointer to do it at the right time.
Non-static class members intrinsically use a this pointer. It's a raw pointer and that can't be changed.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to make a shared pointer to my class.
Given that, when is it ever appropriate for me to explicitly use a this pointer? Are there design paradigms that can prevent bugs related to this?
Wrong question
In a C++ project that uses smart pointers
The issue has nothing to do with smart pointers actually. It is only about ownership.
Smart pointers are just tools
They change nothing WRT the concept of ownership, esp. the need to have well-defined ownership in your program, the fact that ownership can be voluntarily transferred, but cannot be taken by a client.
You must understand that smart pointers (also locks and other RAII objects) represent a value and a relationship WRT this value at the same time. A shared_ptr is a reference to an object and establishes a relationship: the object must not be destroyed before this shared_ptr, and when this shared_ptr is destroyed, if it is the last one aliasing this object, the object must be destroyed immediately. (unique_ptr can be viewed as a special case of shared_ptr where there is zero aliasing by definition, so the unique_ptr is always the last one aliasing an object.)
Why you should use smart pointers
It is recommended to use smart pointers because they express a lot with only variables and functions declarations.
Smart pointers can only express a well-defined design, they don't take away the need to define ownership. In contrast, garbage collection takes away the need to define who is responsible for memory deallocation. (But do not take away the need to define who is responsible for other resources clean-up.)
Even in non-purely functional garbage collected languages, you need to make ownership clear: you don't want to overwrite the value of an object if other components still need the old value. This is notably true in Java, where the concept of ownership of mutable data structure is extremely important in threaded programs.
What about raw pointers?
The use of a raw pointer does not mean there is no ownership. It's just not described by a variable declaration. It can be described in comments, in your design documents, etc.
That's why many C++ programmers consider that using raw pointers instead of the adequate smart pointer is inferior: because it's less expressive (I have avoided the terms "good" and "bad" on purpose). I believe the Linux kernel would be more readable with a few C++ objects to express relationships.
You can implement a specific design with or without smart pointers. The implementation that uses smart pointer appropriately will be considered superior by many C++ programmers.
Your real question
In a C++ project, what is a good design philosophy regarding use of "this"?
That's awfully vague.
It's dangerous to store the raw pointer for later use.
Why do you need to a pointer for later use?
You've given up control of object deletion and trust the responsible component to do it at the right time.
Indeed, some component is responsible for the lifetime of the variable. You cannot take the responsibility: it has to be transferred.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to use my class.
Obviously, since the caller is not informed that the function will hide a pointer and use it later without the control of the caller, you are creating bugs.
The solution is obviously to either:
transfer responsibility to handle the lifetime of the object to the function
ensure that the pointer is only saved and used under the control of the caller
Only in the first case, you might end up with a smart pointer in the class implementation.
The source of your problem
I think that your problem is that you are trying hard to complicate matters using smart pointers. Smart pointers are tools to make things easier, not harder. If smart pointers complicate your specification, then rethink your spec in term of simpler things.
Don't try to introduce smart pointers as a solution before you have a problem.
Only introduce smart pointers to solve a specific well-defined problem. Because you don't describe a specific well-defined problem, it is not possible to discuss a specific solution (involving smart pointers or not).
While i don't have a general answer or some idiom, there is boost::enable_shared_from_this . It allows you to get a shared_ptr managing an object that is already managed by shared_ptr. Since in a member function you have no reference to those managing shared_ptr's, enable_shared_ptr does allow you to get a shared_ptr instance and pass that when you need to pass the this pointer.
But this won't solve the issue of passing this from within the constructor, since at that time, no shared_ptr is managing your object yet.
One example of correct use is return *this; in functions like operator++() and operator<<().
When you are using a smart pointer class, you are right that is dangerous to directly expose "this". There are some pointer classes related to boost::shared_ptr<T> that may be of use:
boost::enable_shared_from_this<T>
Provides the ability to have an object return a shared pointer to itself that uses the same reference counting data as an existing shared pointer to the object
boost::weak_ptr<T>
Works hand-in-hand with shared pointers, but do not hold a reference to the object. If all the shared pointers go away and the object is released, a weak pointer will be able to tell that the object no longer exists and will return you NULL instead of a pointer to invalid memory. You can use weak pointers to get shared pointers to a valid reference-counted object.
Neither of these is foolproof, of course, but they'll at least make your code more stable and secure while providing appropriate access and reference counting for your objects.
If you need to use this, just use it explicitly. Smart pointers wrap only pointers of the objects they own - either exclusivelly (unique_ptr) or in a shared manner (shared_ptr).
I personally like to use the this pointer when accessing member variables of the class. For example:
void foo::bar ()
{
this->some_var += 7;
}
It's just a harmless question of style. Some people like it, somepeople don't.
But using the this pointer for any other thing is likely to cause problems. If you really need to do fancy things with it, you should really reconsider your design. I once saw some code that, in the constructor of a class, it assigned the this pointer to another pointer stored somewhere else! That's just crazy, and I can't ever think of a reason to do that. The whole code was a huge mess, by the way.
Can you tell us what exactly do you want to do with the pointer?
Another option is using intrusive smart pointers, and taking care of reference counting within the object itself, not the pointers. This requires a bit more work, but is actually more efficient and easy to control.
Another reason to pass around this is if you want to keep a central registry of all of the objects. In the constructor, an object calls a static method of the registry with this. Its useful for various publish/subscribe mechanisms, or when you don't want the registry to need knowledge of what objects/classes are in the system.