# Reference Counting Helpers ## RefPtr versus nsCOMPtr The general rule of thumb is to use `nsCOMPtr` when `T` is an interface type which inherits from `nsISupports`, and `RefPtr` when `T` is a concrete type. This basic rule derives from some `nsCOMPtr` 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` 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`, 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.