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 once 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.