This article needs a technical review. How you can help.
This article needs an editorial review. How you can help.
Gecko code uses both
RefPtr as smart pointers. This guide provides some explanation and advice about how to choose between them.
General Rule of Thumb for
The general rule of thumb is to use
T is an interface type and
T is a concrete type.
This basic rule derives from the fact that some of the
nsCOMPtr<T> code is factored into the
nsCOMPtr_base base class, which stores the underlying
mRawPtr as an
nsISupports* (although, confusingly, debug builds don't work this way). This design saves some space in the binary (or at least it used to). Since
nsCOMPtr stores the pointer as an
nsISupports*, it must be possible to unambiguously cast from
nsISupports*. Many concrete classes inherit from
nsISupports in more than one way, so they cannot be unambiguously cast to
nsISupports*. Thus, these concrete classes cannot be used with
While is possible to use
nsCOMPtr<T> on concrete classes
T that only singly inherit from
nsISupports, it is best to avoid doing so. In the future, more base classes might be added to
T that would then cause unrelated code to break, which would be very confusing. Hence the interface versus concrete class rule of thumb: interfaces will never multiply inherit from
nsISupports, so they can always use be used with
nsCOMPtr without fear of breaking in the future. Concrete classes should only be used with
nsCOMPtr<T> also requires that you can
QueryInterface to type
T. It does this so that it can assert that
mRawPtr is a canonical
T pointer (i.e., that
mRawPtr->QueryInterface(T_IID) == mRawPtr).
do_QueryInterface helper is only available when assigning to
nsCOMPtr. It also requires that the argument singly inherit from
nsISupports (since the type of the argument is
nsISupports*). For other cases, there is
do_QueryObject, which is essentially a more powerful form of
do_QueryInterface. It differs from
do_QueryInterface as follows:
nsCOMPtr_helper, so it can be assigned into both
RefPtr. The downside of this inheritance is that
do_QueryObjectrequires an extra virtual call to
operator()in the helper method.
do_QueryObjectis templated on the argument type, so it's possible to pass in objects that multiply inherit from
nsISupports. However, when the destination type is an XPCOM interface, it's probably better to
static_castto a class that unambiguously inherits from
do_QueryInterfacein such cases.