Game Development Reference
In-Depth Information
Why not use smart pointers for everything? There are two major pitfalls to using
smart pointers. First, maintaining those internal reference counts adds a small mem-
ory and CPU overhead. This is rarely noticeable, but if you have thousands of objects
to manage and want to process them each frame, it can really start to add up. The
other problem is that smart pointers tend to take away some of your control over the
memory. For example, you may not have a clear understanding of which systems
could be holding a reference to any particular game object. When you
”
that object by removing the reference, another reference may keep the object alive
longer than you intended. If I had a dollar for every smart pointer bug I fixed over
the years, I
“
destroy
d be a rich man.
So which one do you choose? It depends on the purpose. If you have a pointer to an
object that is not visible outside of the owner, a naked pointer is just fine. An exam-
ple of this is the
m_pProcessManager
member of
BaseGameLogic
. This pointer is
never accessed outside of the class or its children so there
'
s no risk for another sys-
tem to hold onto it. It can safely be destroyed without affecting any other systems.
Notice that the only access to this pointer is through the
BaseGameLogic::
AttachProcess()
method. This is a great pattern to follow because it means that
no one outside of the
BaseGameLogic
even has any idea that the
ProcessManager
class exists. You could create multiple
ProcessManager
classes or remove it entirely
without having to touch any other code.
By contrast, if you look at the event system, all events are stored as smart pointers.
This is because it
'
s never clear who might be hanging on to a reference to these
objects. This is by design; the event receiver can hold on to the event without fear
of it being destroyed, or it cannot hold on to it and the event will be happily
destroyed after the event is handled.
'
Reference counting stores an integer value that counts how many other objects are
currently referring to the object in question. Reference counting is a common mech-
anism in memory management. DirectX objects implement the COM-based
IUn-
known
interface, which uses reference counting. Two methods that are central to
this task are
AddRef()
and
Release()
. The following code shows how this works:
MySound *sound = new MySound;
sound->AddRef(); // reference count is now 1
After you construct a reference-counted object, you call the
AddRef()
method to
increase the integer reference counter by one. When the pointer variable goes out of
scope, by normal scoping rules or by the destruction of the container class, you must
call
Release()
.
Release()
will decrement the reference counter and destroy the