nsRefPtr

RefPtr (formerly known as nsRefPtr, see bug 1207245) is a general class to implement reference counting pointers for objects. It is similar to nsCOMPtr, but does not require that the type be an XPCOM interface.  Like with nsCOMPtr, it is the responsibility of the object itself to implement reference counting. This is done using the functions AddRef() and Release(), which respectively modify a variable of type nsAutoRefCnt, which basically is a wrapper around a count of the number of references refering to the class.

When should I use nsCOMPtr versus RefPtr?

Any time you are holding an XPCOM interface pointer, you should be using nsCOMPtr.  So:

  nsCOMPtr<nsISupports> a;
  nsCOMPtr<nsIFoo> foo;

Any time you are holding a pointer to a concrete class--even if it implements one or more XPCOM interfaces--you should be using RefPtr:

  RefPtr<nsFoo> foo;  // class that implements nsIFoo;
  RefPtr<Bar> bar;    // some random class that I want ref-counted but has nothing to do with XPCOM:
                      // Just implement AddRef() and Release() and it will work with RefPtr

Note: in the above example, "nsCOMPtr<nsFoo>" might compile and work OK (it won't if your XPCOM class multiply-inherits nsISupports).   But this is considered Bad Form, and may soon be made a compile-time error.  Don't do it!

Can I QueryInterface a RefPtr to get a nsCOMPtr from the object it points to?

Sure.  Instead of using "do_QueryInterface()" (which is used for nsCOMPtrs), use "do_QueryObject()", which works with RefPtrs:

  RefPtr<nsFoo> foo;    // nsFoo implements nsIFoo and nsIBar XPCOM interfaces
  nsCOMPtr<nsIBar> bar(do_QueryObject(foo)); // constructor initiatialization, slightly faster
or 
  bar = do_QueryObject(foo);
  if (bar) { ... }          // generally you want to check for success

Can I QueryInterface an nsCOMPtr back to a RefPtr?

Yes. If the concrete class has its own XPCOM IID (not true by default, but one can be added), you can also QI from an XPCOM pointer to a concrete type:

bar = do_QueryObject(foo);
if (bar) { ... } 

See this post for more details.

Document Tags and Contributors

 Contributors to this page: gsquelart, teoli, jduell, Accatagon
 Last updated by: gsquelart,