Reference Counting Helpers
RefPtr versus nsCOMPtr
The general rule of thumb is to use nsCOMPtr<T>
when T
is an
interface type which inherits from nsISupports
, and RefPtr<T>
when
T
is a concrete type.
This basic rule derives from some nsCOMPtr<T>
code being factored into
the nsCOMPtr_base
base class, which stores the pointer as a
nsISupports*
. This design was intended to save some space in the binary
(though it is unclear if it still does). Since nsCOMPtr
stores the
pointer as nsISupports*
, it must be possible to unambiguously cast from
T*
to nsISupports**
. Many concrete classes inherit from more than
one XPCOM interface, meaning that they cannot be used with nsCOMPtr
,
which leads to the suggestion to use RefPtr
for these classes.
nsCOMPtr<T>
also requires that the target type T
be a valid target
for QueryInterface
so that it can assert that the stored pointer is a
canonical T
pointer (i.e. that mRawPtr->QueryInterface(T_IID) ==
mRawPtr
).
do_XXX() nsCOMPtr helpers
There are a number of do_XXX
helper methods across the codebase which can
be assigned into nsCOMPtr
(and sometimes RefPtr
) to perform explicit
operations based on the target pointer type.
In general, when these operations succeed, they will initialize the smart
pointer with a valid value, and otherwise they will silently initialize the
smart pointer to nullptr
.
do_QueryInterface
and do_QueryObject
Attempts to cast the provided object to the target class using the XPCOM
QueryInterface
mechanism. In general, use do_QueryInterface
may only
be used to cast between interface types in a nsCOMPtr<T>
, and
do_QueryObject
in situations when downcasting to concrete types.
do_GetInterface
Looks up an object implementing the requested interface using the
nsIInterfaceRequestor
interface. If the target object doesn’t implement
nsIInterfaceRequestor
or doesn’t provide the given interface, initializes
the smart pointer with nullptr
.
do_GetService
Looks up the component defined by the passed-in CID or ContractID string in
the component manager, and returns a pointer to the service instance. This
may start the service if it hasn’t been started already. The resulting
service will be cast to the target interface type using QueryInterface
.
do_CreateInstance
Looks up the component defined by the passed-in CID or ContractID string in
the component manager, creates and returns a new instance. The resulting
object will be cast to the target interface type using QueryInterface
.
do_QueryReferent
and do_GetWeakReference
When passed a nsIWeakReference*
(e.g. from a nsWeakPtr
),
do_QueryReferent
attempts to re-acquire a strong reference to the held
type, and cast it to the target type with QueryInterface
. Initializes the
smart pointer with nullptr
if either of these steps fail.
In contrast do_GetWeakReference
does the opposite, using
QueryInterface
to cast the type to nsISupportsWeakReference*
, and
acquire a nsIWeakReference*
to the passed-in object.