Revision 176862 of Using nsCOMPtr

  • Revision slug: Using_nsCOMPtr
  • Revision title: Using nsCOMPtr
  • Revision id: 176862
  • Created:
  • Creator: Jorend
  • Is current revision? No
  • Comment /* The Basics */ formatting
Tags: 

Revision Content

This document is the sum total of everything written down about nsCOMPtr. If you have a question about nsCOMPtr, and this document doesn't answer it, there probably isn't a document that answers it. You'll have to turn to the XPCOM newgroup or another experienced nsCOMPtr user, or find the answer by experimentation.

If you've never used nsCOMPtr before, you're starting in the right place. Just keep reading. You'll know when to stop. After you've been using nsCOMPtrs for a while, and you reach unfamiliar territory, or run into compiler errors; you may want to return to this document to get help from the {{mediawiki.external('#Reference_Manual Reference Manual')}} or the {{mediawiki.external('#FAQ FAQ')}}.

Status, Recent Changes, and Plans

I'm sorry this section is in the way for first-time readers. You may want to skip ahead to the {{mediawiki.external('#contents table of contents')}}, or directly to the {{mediawiki.external('#Getting_Started_Guide Getting Started Guide')}}, the {{mediawiki.external('#Reference_Manual Reference Manual')}}, or the {{mediawiki.external('#FAQ FAQ')}}. I put this section at the top so that checking for recent changes will be easy.

Recent changes to nsCOMPtr

Most recent first

  • Made == and != between an nsCOMPtr and a raw pointer (or a literal 0 or nsnull) work correctly on all compilers. See bug 65664.
  • Made {{mediawiki.external('#ref_getter_AddRefs <code>getter_AddRefs( nsCOMPtr& )</code>')}} apply the same {{mediawiki.external('#ref_assert_NoQueryNeeded type-safety check')}} that the simple assignment forms do.
  • Added do_CreateInstance.
  • Added do_GetService.
  • Eliminated the need to cast getter_AddRefs when an nsISupports** is needed.
  • Relaxed the invariant for nsCOMPtr<nsISupports>, so that it is now a pointer to any {{mediawiki.external('XP')}}COM interface.
  • Added {{mediawiki.external('#ref_do_QueryReferent <code>do_QueryReferent</code>')}} to make using nsIWeakReferences easier.

Plans for nsCOMPtr

  • bug #59212: as soon as we test on more compilers, start recommending already_AddRefed as a function result.
  • bug #59414: making operator& private may help prevent some {{mediawiki.external('#ref_casting leaks caused by casting')}}
  • Move the factored nsCOMPtr routines into their own library, to reduce nsCOMPtr clients' dependency on the XPCOM library.

Recent changes to this document

  • Removed the statement that == and != between an nsCOMPtr and a raw pointer or literal 0 does not work on some compilers since it is no longer true.
  • Added an entire section to the Getting Started Guide on {{mediawiki.external('#guide_nsCOMPtr_in_APIs <code>nsCOMPtr</code>s in function signatures')}}
  • Added references to recent bugs influencing the use of nsCOMPtr machinery: #59212, and #59414
  • Fixed comparisons {{mediawiki.external('#comparison1 1')}} and {{mediawiki.external('#comparison3 3')}}, as per comments by Morten Welinder
  • Updated examples to prefer direct initialization over copy initialization.


Getting Started Guide

If you have never used nsCOMPtrs before, this section is for you. If you're already familiar with nsCOMPtrs, then you might want to skip ahead to the {{mediawiki.external('#Reference_Manual Reference Manual')}} or the {{mediawiki.external('#FAQ FAQ')}}. Don't worry; the Getting Started Guide is short.

Introduction

What is nsCOMPtr?

nsCOMPtr is a tool to help prevent leaks.

nsCOMPtr is a "smart pointer". It is a template class that acts, syntactically, just like an ordinary pointer in C or C++, i.e., you can apply * or -> to it to "get to" what it points at. nsCOMPtr is smart in that, unlike a raw C++ pointer to an XPCOM object, nsCOMPtr manages AddRef, Release, and QueryInterface for you. nsCOMPtr is defined in the source files{{mediawiki.internal('#link_source <span class=\"plain\">' .. # .. '</span>', "en")}}:

...though you probably don't want to look in there, just yet.

With nsCOMPtr, you can write code that is shorter, cleaner, clearer, and safer, than you can with raw {{mediawiki.external('XP')}}COM interface pointers.

[XP]COM Basics: Ownership and Reference Counting

This is a quick refresher on some fundamental issues of {{mediawiki.external('XP')}}COM. You should already know this, and should be able to just skim this short section. If this is unfamiliar material, you're not ready for nsCOMPtrs yet. A good place to learn about the basic rules and reasoning behind COM is in Essential COM{{mediawiki.internal('#link_essentialcom <span class=\"plain\">' .. # .. '</span>', "en")}} by Don Box{{mediawiki.internal('#link_donbox <span class=\"plain\">' .. # .. '</span>', "en")}}. Don Box gets into more of the details, traps, and pitfalls of COM in Effective COM{{mediawiki.internal('#link_effectivecom <span class=\"plain\">' .. # .. '</span>', "en")}}. You should also have a reasonable knowledge of C++. Probably the three most helpful books on this topic are The C Programming Language{{mediawiki.internal('#link_cppprogramminglanguage <span class=\"plain\">' .. # .. '</span>', "en")}} by Bjarne Stroustrup, Effective C {{mediawiki.internal('#link_effectivecpp <span class=\"plain\">' .. # .. '</span>', "en")}}, and More Effective C {{mediawiki.internal('#link_moreeffectivecpp <span class=\"plain\">' .. # .. '</span>', "en")}} by Scott Meyers.

All {{mediawiki.external('XP')}}COM objects are allocated on the heap. Clients don't get to know much about the implementation of any such object. They reference it only through a pointer to an `interface', i.e., the static type of the pointer is a pointer to an abstract base class, the actual object pointed to is a class derived from that abstract base class. The {{mediawiki.external('XP')}}COM object is said to `implement that interface'. The clients reference to the object is typically called `an interface pointer'.

An object may implement many interfaces. Each interface is (at least conceptually) separately `reference counted'. That is, the interface keeps a count of the number of clients holding references to it. When that count goes to zero, the interface may delete itself. Clients are expected to keep this reference count accurate by incrementing it when they acquire a reference to the interface, and decrementing it before they let go. To facilitate this, all interfaces inherit from an abstract base class that provides the member functions AddRef, and Release.

A rule of {{mediawiki.external('XP')}}COM is that any function that creates or returns an interface pointer will have already AddRefed it. The caller can then hold onto the reference indefinitely, calling Release when it no longer needs it. When the last pointer to an interface is Released, the interface (and consequently, typically the underlying object) will delete itself. As long as there is an outstanding AddRef against the interface, it continues to exist. If you forget to call Release, the object will leak, i.e., the storage for that object will never be reclaimed. Leaks are bad :-).

A reference through which you will call AddRef and Release is called an owning reference. It holds a stake in the underlying object. That object cannot go away until the owning reference has relinquished its claim. Not all references need to be owning references. In fact, if two objects somehow end up owning each other (even transitively) it becomes difficult for either of those object to be reclaimed without adding some `out-of-band' mechanism for breaking the ownership cycle. The document Some COM Ownership Guidelines{{mediawiki.internal('#link_ownershipguidelines <span class=\"plain\">' .. # .. '</span>', "en")}} provides some hints on when ownership is needed. The following lists are good starting point, but by no means complete.

You use an owning reference when

  • you created the object;
  • you got the object from a function that might have created it, e.g., any `getter' function, such as QueryInterface, or CreateInstance. All good getters AddRef the interface pointers they produce, thus providing you with an owning reference;
  • you will hold onto the reference longer than the scope of the function in which you acquired it, e.g., you got it as a parameter, but you're hanging onto it in a member variable [see, for example, {{mediawiki.external('#comparison1 Comparison 1')}}, below].

You don't need an owning reference when

  • the object is passed in as a parameter, and you don't need to keep it any longer than the scope of this function;
  • the object's lifetime is known to contain yours in some well defined way, e.g., in the nodes of a tree, parent nodes keep owning references to their children, children need not keep owning references to their parents.

It turns out that reference counting by hand is hard for programmers to get right. It may sound simple, but in practice it's very easy to forget to Release at the appropriate moment. Or to AddRef too many or too few times.

How does nsCOMPtr help?

nsCOMPtr manages AddRef, Release, and other red-tape for you. An nsCOMPtr looks and acts as much like a raw {{mediawiki.external('XP')}}COM interface pointer as C allows, but it knows it owns the object it points to. This takes a little getting used to on your part, but ends up with less typing, clearer, safer code, and less leaks.

For instance, here is a typical snippet of code (at its most compact) where you assign a {{mediawiki.external('XP')}}COM interface pointer into a member variable, i.e., the body of a `setter' function, side-by-side using raw {{mediawiki.external('XP')}}COM interface pointers and nsCOMPtrs.

Comparison 1. Setting a member variable.
// raw [XP]COM interface pointers...
// given: |nsIFoo* mFooPtr;|

/*
   |AddRef| the new value if it's not
   |NULL|; assign it in; and |Release|
   the old value, if any (so we don't
   leak it).
 
   This order of assignment is special
   and must be used to avoid particular
   ownership bugs.
 */

NS_IF_ADDREF(aFooPtr);
nsIFoo* temp = mFooPtr;
mFooPtr = aFooPtr;
NS_IF_RELEASE(temp);
// |nsCOMPtr|...
// given: |nsCOMPtr<nsIFoo> mFooPtr;|

/*
   This assignment automatically
   |Release|s the old value in
   |mFooPtr|, if any, and |AddRef|s the
   new one, in the appropriate sequence
   to avoid the ownership bug mentioned
   earlier.
 */





mFooPtr = aFooPtr;

Additionally, the class using raw {{mediawiki.external('XP')}}COM interface pointers will need a destructor to Release mFooPtr; and a constructor to ensure that mFooPtr is initially set to NULL (or some other reasonable value).

nsCOMPtr helps you write code that is leak-proof, exception safe, and significantly less verbose than you would with raw {{mediawiki.external('XP')}}COM interface pointers. With nsCOMPtr, you may never have to call AddRef, Release, or QueryInterface by hand.

You still have to understand {{mediawiki.external('XP')}}COM. You still have to know which functions return interface pointers that have already been AddRefed and which don't. You still have to ensure your program logic doesn't produce circularly referencing garbage. nsCOMPtr is not a panacea. It is, however, helpful, easy to use, well-tested, and polite. It doesn't require that a function author cooperate with you, nor does your use force others to use it.

Using nsCOMPtr

The Basics

In most cases, you'll use an nsCOMPtr exactly as you would a raw {{mediawiki.external('XP')}}COM interface pointer. Note the slight difference in declaration.

Comparison 2. Similarities: nsCOMPtr is syntactically similar to raw {{mediawiki.external('XP')}}COM interface pointers.
// raw [XP]COM interface pointers...

nsIFoo* fooPtr = 0;
 // ...
fooPtr->SomeFunction(x, y, z);
AnotherFunction(fooPtr);

if ( fooPtr )
  // ...

if ( fooPtr == foo2Ptr )
  // ...
// |nsCOMPtr|...

nsCOMPtr<nsIFoo> fooPtr;
// ...
fooPtr->SomeFunction(x, y, z);
AnotherFunction(fooPtr);

if ( fooPtr )
  // ...

if ( fooPtr == foo2Ptr )
  // ...

There are two main differences. First: you no longer need, nor are you allowed, to call AddRef or Release.

Comparison 3. Differences: AddRef and Release are illegal for nsCOMPtrs.
// raw [XP]COM interface pointers...
// given: |nsIFoo* mFooPtr;|

  /*
    Note: this sequence is not the
    correct order to do assign
    raw pointers anyway (see
    [#comparison1 Comparison 1]) but I need it
    for this comparison.
  */

NS_IF_RELEASE(mFooPtr);

mFooPtr = aFooPtr;
NS_IF_ADDREF(mFooPtr);

// |nsCOMPtr|...
// given: |nsCOMPtr<nsIFoo> mFooPtr;|

  /*
    You no longer need, nor will the
    compiler let you, call |AddRef|,
    or |Release|.
  */



NS_IF_RELEASE(mFooPtr);
  // Error: |Release| is private
mFooPtr = aFooPtr;
NS_IF_ADDREF(mFooPtr);
  // Error: |AddRef| is private

Second: you can't just pass the address of an nsCOMPtr to a getter expecting to return a result through a raw {{mediawiki.external('XP')}}COM interface pointer parameter. You have to `annotate' the nsCOMPtr with the {{mediawiki.external('#ref_getter_AddRefs <code>getter_AddRefs</code>')}} directive.

Comparison 4. Differences: apply getter_AddRefs when using an nsCOMPtr as a `out parameter'.
// raw [XP]COM interface pointers...

nsIFoo* foo;

GetFoo(&foo);
// |nsCOMPtr|s...

nsCOMPtr<nsIFoo> foo;

GetFoo(getter_AddRefs(foo));

That's it. You now know enough to start using nsCOMPtrs. There are a few other details you will want to know as you use nsCOMPtr in more complicated situations, but what you've just learned will cover 90% of your uses.

A Few Details

There are a couple more things that will help you get the most out of nsCOMPtr.

Very often, you first get an interface pointer by calling QueryInterface. QueryInterface is a getter like any other, and you already know one way to call it, applying the getter_AddRefs rule, as described above.

The hard way to QueryInterface into an nsCOMPtr.
// A way (though not the best way) to |QueryInterface| into an |nsCOMPtr|...

nsCOMPtr<nsIFoo> foo;

nsresult rv = bar->QueryInterface(NS_GET_IID(nsIFoo), getter_AddRefs(foo));

  // Or, if you're a savvy [XP]COM programmer,
  //  you use the type-safe version...
nsresult rv = CallQueryInterface(bar, getter_AddRefs(foo));

QueryInterface is used so frequently, though, that nsCOMPtr has a special facility to call it. This facility is type-safe, and it enables an nsCOMPtr to be directly constructed from the result of QueryInterface. Construction from the correct value is more efficient that construction followed by assignment. This facility is the {{mediawiki.external('#quad2 <code>do_QueryInterface</code>')}} directive. Using do_QueryInterface, the sample above would look like this

How to QueryInterface into an nsCOMPtr.
// The best way to |QueryInterface| into an |nsCOMPtr|...

nsresult rv;
nsCOMPtr<nsIFoo> foo( do_QueryInterface(bar, &rv) );

  // Or, if you don't care about the |nsresult|
nsCOMPtr<nsIFoo> foo( do_QueryInterface(bar) );

nsCOMPtr happily calls AddRef and Release implicitly. This same favor is not extended to QueryInterface. nsCOMPtr does not QueryInterface on assignment without your explicit permission in the form of the do_QueryInterface directive. You need never worry about hidden queries. However, be aware that if you should have queried but didn't, e.g., when assigning in a raw pointer where C allows the assignment, but {{mediawiki.external('XP')}}COM wouldn't, nsCOMPtr will {{mediawiki.external('#ref_assert_NoQueryNeeded assert at runtime')}}. Use do_QueryInterface whenever you assign in a pointer to a {{mediawiki.external('XP')}}COM interface of a different type, even if that type happens to derive from the base type of the nsCOMPtr

Comparison 6. do_QueryInterface prevents {{mediawiki.external('XP')}}COM type errors.
class nsIBar
  : public nsIFoo ... { ... };

nsIBar* p = ...;

  // C   thinks every |nsIBar*| is an
  //  |nsIFoo*|, therefore, C   allows
  //  this...
nsCOMPtr<nsIFoo> foo = p;
  //  ...even though it is an [XP]COM
  //  type error
class nsIBar
  : public nsIFoo ... { ... };

nsIBar* p = ...;



  // No type error here...
nsCOMPtr<nsIFoo> foo( do_QueryInterface(p) );


Remember, the C type system and the {{mediawiki.external('XP')}}COM type system are really two independent things. Because {{mediawiki.external('XP')}}COM interfaces are expressed as abstract C base classes, you may be tempted to let C handle the differences, or to use C casts to navigate between interface types. This is wrong. The only sanctioned way to get between {{mediawiki.external('XP')}}COM types is with QueryInterface. In the example above, there is no reason to assume that the nsIFoo* C pulls out of p would be the same one that p->QueryInterface() would return.

{{mediawiki.external('#quad3 <code>dont_AddRef</code>')}} is a similar directive that helps you when you assign in a pointer that has already been AddRefed, e.g., because you called a getter that returned the pointer as its function result.

Using dont_AddRef.
nsCOMPtr<nsIFoo> foo( dont_AddRef(CreateFoo()) );
  // |CreateFoo| |AddRef|s its result, as all good getters do

Something nsCOMPtr Doesn't Do

An nsCOMPtr does all that is necessary to behave as an owning reference. A given nsCOMPtr does not, however, cooperate in making other owning pointers. After learning how nsCOMPtr automatically AddRefs a pointer as it is being assigned in, the natural assumption is that it does the same thing when assigning out. Here is a snippet of code that demonstrates this misconception.

// Incorrect assumptions about |nsCOMPtr|...

nsresult
nsCacheRecord::GetFileSpec( nsIFileSpec** aFileSpecResult )
    /*
      ...fills in the callers |nsFileSpec*| (which the caller supplied
      the address of) with a copy of my member variable |mFileSpec|,
      an |nsCOMPtr|.  I.e., this function is a `getter'.

      Remember: good [XP]COM getters always |AddRef| their result.
    */
  {
    // ...
    *aFileSpec = mFileSpec;
      // the |nsCOMPtr| should take care of the refcount here, right?
    return NS_OK;
  }

Plainly, the author believed (though perhaps with some question) that the nsCOMPtr, mFileSpec, would AddRef automatically as it was assigned into *aFileSpec. This is not the case. An nsCOMPtr automatically calls AddRef and Release (only) on its own behalf. In all other situations, it is designed to be a drop in replacement for a raw {{mediawiki.external('XP')}}COM pointer. Where ever an nsCOMPtr is used in a situation where a raw pointer is needed, the nsCOMPtr automatically provides one.

// |nsCOMPtr| produces a raw pointer when needed...

nsCOMPtr<nsIFoo> foo = ...;

  // 1.  Assigning into a raw pointer
nsIFoo* raw_foo = foo;

  // 2.  Assigning into another |nsCOMPtr|
nsCOMPtr<nsIFoo> foo2 = foo;

  // 3.  As a parameter
SetFoo(foo);

  // 4.  Testing the value in an |if| expression
  // 5.  Calling a member function
if ( foo )
  foo->DoSomething();

In all of these cases, pretty much the exact same code is executed (case 2 is slightly different, but the intent is the same). In each case, you are essentially extracting the raw pointer value for your own purpose. If the nsCOMPtr AddRefed the value each time you did that, cases 4 and 5 would obviously always generate leaks. SetFoo, from case 3, would have to be written two different ways when given an nsCOMPtr, it would know the value was already AddRefed, and when given a raw pointer it would assume the value was not AddRefed. Actually the contradictions run deeper than that. All these cases show that automatically AddRefing on `output' makes nsCOMPtrs and raw-pointers act differently from the point of view of the clients. The goal is to make them act the same so that nsCOMPtrs can be a drop in replacement (modulo managing its own `ownership').

Given what you now know, the rule is predictable. As described above, and unless you tell it otherwise, an nsCOMPtr AddRefs when you assign in to it. It does nothing when you assign out of it.

Where should I use nsCOMPtrs?

You should use an nsCOMPtr any place you use an interface pointer as an owning reference, i.e., where you call AddRef and Release on it. You should use nsCOMPtr as a member variable, where it will simplify setters, and eliminate constructors, destructors, and assignment operators. You should use nsCOMPtr on the stack, where it makes calling QueryInterface almost pleasant, and eliminates the complex logic that falls out of error handling.

Where shouldn't I use nsCOMPtrs?

Don't use nsCOMPtrs where you don't need an owning reference. See Some COM Ownership Guidelines{{mediawiki.internal('#link_ownershipguidelines <span class=\"plain\">' .. # .. '</span>', "en")}}. nsCOMPtr is designed to be used with {{mediawiki.external('XP')}}COM interfaces, so don't use it with non-interfaces with specific exceptions described {{mediawiki.external('#guide_nsCOMPtrs_for_concrete_classes below')}}. Don't use nsCOMPtrs in {{mediawiki.external('XP')}}COM interfaces. Don't use them in plain old C code; nsCOMPtrs are, of course, a C only construct. {{mediawiki.external('#ref_casting Never cast')}} an nsCOMPtr, it's almost guaranteed to leak.

nsCOMPtrs for non-interface classes

Appropriately formatted answer to come, in the meanwhile, the full details are available in this news posting.

nsCOMPtrs in function signatures

In general, you won't want to use nsCOMPtr in the signature of XPCOM (i.e., `scriptable') functions. nsCOMPtr is not currently directly supported by IDL. However, you may sometime be tempted to use an nsCOMPtr in a non-scriptable function.

nsCOMPtr<T> f() don't return an nsCOMPtr

This practice is dangerous. Returning an AddRefed pointer in almost any form as a function result leads to several potential errors, some of which are leaks, some of which are dangling pointers. Returning an nsCOMPtr may seem like a good idea (since it tells clients you are giving them ownership), however it can be the cause of an dangling pointer. Consider:

// Don't return |nsCOMPtr|s...
nsCOMPtr<nsIFoo> CreateFoo();
// ...

nsIFoo* myFoo = CreateFoo(); // Oops: |myFoo| now dangles!
  // |CreateFoo| returns an |nsCOMPtr|, which
  //  automatically |Release|s right after this
  //  assignment.  Now |myFoo| refers to a
  //  deleted object.

You can tell callers you are giving them ownership in a way that doesn't pose this hazard by returning a already_AddRefed<T> (see bug #59212). An nsCOMPtr knows not to AddRef a value that is already_AddRefed.

// Preferred form: if you must return a pointer, use |already_AddRefed|...
already_AddRefed<nsIFoo> CreateFoo();
// ...

nsIFoo* myFoo1 = CreateFoo(); // doesn't dangle
nsCOMPtr<nsIFoo> myFoo2( CreateFoo() ); // doesn't leak
nsCOMPtr<nsIFoo> myFoo3( dont_AddRef(CreateFoo()) ); // redundant, but legal and correct

Compare this to the most frequent leaks caused by returning a raw pointer you have already AddRefed:

// Don't return raw pointers; that incites leaks...
nsIFoo* CreateFoo(); // returns an |AddRef|ed pointer
// ...

nsCOMPtr<nsIFoo> myFoo = CreateFoo(); // Oops: leak;
nsCOMPtr<nsIFoo> myFoo( dont_AddRef(CreateFoo()) );
  // Since |CreateFoo| already |AddRef|s its result, we must remind
  //  our |nsCOMPtr| not to.  It's easy to forget.  Prevent it in advance
  //  by not returning pointers as function results, or else by returning
  //  an |already_AddRefed<T>| as above.
void f( nsCOMPtr<T> ) don't pass an nsCOMPtr by value

This practice is wasteful, but not otherwise harmful. There is no need to AddRef parameters, as they are guaranteed to live as long as the function call. You only need to AddRef them as you store them in a structure that will live longer than the function call. Which means the appropriate member of that structure should be an nsCOMPtr, not the function parameter. Additionally, this signature may confuse callers into thinking they need an nsCOMPtr just to call the function.

void f( const nsCOMPtr<T>& ) don't pass an nsCOMPtr by const reference

Exactly as the signature above, this practice is wasteful, but not otherwise harmful, and has the same impact as passing an nsCOMPtr by value if the caller only supplied a raw pointer.

void f( nsCOMPtr<T>* ) avoid passing an nsCOMPtr by address, if possible

This practice requires callers to have an nsCOMPtr, and requires them to do a little extra work, as operator& for nsCOMPtrs is private (to help prevent {{mediawiki.external('#ref_casting leaks caused by casting')}}; also see bug #59414). This is an acceptable way to declare `in/out' parameters, but prefer passing nsCOMPtrs by reference, as below.

// Passing an |nsCOMPtr| by pointer requires extra work...
void f( nsCOMPtr<nsIFoo>* );
// ...

nsCOMPtr<nsIFoo> myFoo = ...;

f( address_of(myFoo) );
void f( nsCOMPtr<T>& ) do pass an nsCOMPtr by reference for `in/out' parameters

This is the prefered scheme for providing `in/out' parameters. If you were to use a raw pointer instead, your function couldn't know what ownership relationship the caller had to the input value, and hence, couldn't know whether to Release it or not before assigning in the new value. By declaring the parameter as an nsCOMPtr&, the relationship is explicit.

Summary

An nsCOMPtr is an owning reference. Whatever it points to has been AddRefed, counting the nsCOMPtr as one of its `owners'. An nsCOMPtr always calls Release before letting go, whether the nsCOMPtr is letting go so that it can point to a different object, or because the nsCOMPtr is going out of scope. Any time a new value is assigned into an nsCOMPtr, the nsCOMPtr automatically always Releases its old referent, if any, and (unless you tell it you already have) AddRefs the new.

You use an nsCOMPtr exactly as you would a raw {{mediawiki.external('XP')}}COM interface pointer in almost all cases [though note the compiler problems shown in {{mediawiki.external('#comparison5 Comparison 5')}}]. You won't have to explictly call AddRef or Release through it, nor will the compiler allow it. The only place you can't use an nsCOMPtr without change is where a raw {{mediawiki.external('XP')}}COM interface pointer is an `out' parameter. In this case, you wrap the nsCOMPtr with {{mediawiki.external('#ref_getter_AddRefs <code>getter_AddRefs</code>')}} [see {{mediawiki.external('#comparison4 Comparison 4')}}].

When assigning into an nsCOMPtr, you will usually just supply another pointer (either a raw {{mediawiki.external('XP')}}COM interface pointer or an nsCOMPtr), with no additional directives [see, e.g., the nsCOMPtr side of {{mediawiki.external('#comparison1 Comparison 1')}}]. As stated above, with no directives, the nsCOMPtr will Release its old referent, if any, and AddRef the new. This is appropriate when the thing you're assigning in hasn't yet been AddRefed to account for the new reference. This is typically the case when you are assigning in a pointer that you didn't call a function to get, e.g., one that was passed in as a parameter, or that you pulled out of a structure.

You can tell nsCOMPtr it doesn't need to AddRef the new value on assignment by wrapping the new value in {{mediawiki.external('#quad3 <code>dont_AddRef</code>')}}. Do this, for example, when you got the new value from a function which, like all good {{mediawiki.external('XP')}}COM getters, already called AddRef on your behalf.

You may not assign in a pointer to a different interface type; you must first query it to the right type [see, e.g., {{mediawiki.external('#comparison6 Comparison 6.')}} and the surrounding discussion]. nsCOMPtr never calls QueryInterface implicitly, i.e., you must call it yourself, or explictly ask nsCOMPtr to call it with {{mediawiki.external('#quad2 <code>do_QueryInterface</code>')}}. The do_QueryInterface directive allows you to do the query as part of the assignment. This better facilitates constructing an nsCOMPtr directly from the right value, rather than constructing it and assigning in the correct value later. Construction alone is more efficient than construction followed by assignment. Prefer construction over assignment whereever reasonable. Be careful not to apply do_QueryInterface to a function returning an AddRefed pointer [see {{mediawiki.external('#quad4 this short section')}} for an explanation]

For more details, continue on to the {{mediawiki.external('#reference_manual Reference Manual')}}.


Reference Manual

This section will help you if you're already familiar with nsCOMPtr but you need details. If you've never use nsCOMPtrs before, you might want to read the {{mediawiki.external('#users_guide Getting Started Guide')}} first. If you're trying to fix a broken build, the {{mediawiki.external('#FAQ FAQ')}} might lead you to the answer more quickly.

  • {{mediawiki.external('#ref_basics Tbe Basics')}}
  • {{mediawiki.external('#ref_assignment Intitialization and Assignment')}}
  • {{mediawiki.external('#ref_parameters Using an <code>nsCOMPtr<T></code> as a <code>T*</code>')}}
  • {{mediawiki.external('#ref_efficiency Efficiency and Correctness')}}
  • {{mediawiki.external('#ref_annoyances Compiler Annoyances')}}

The Basics

Design

An nsCOMPtr is designed to be a complete replacement for raw {{mediawiki.external('XP')}}COM interface pointers where they are used as owning references. Almost any place you could use a raw {{mediawiki.external('XP')}}COM interface pointer, you should be able to use an nsCOMPtr. An nsCOMPtr is the exact same size and shape as a raw {{mediawiki.external('XP')}}COM interface pointer. It can be used as a member variable without introducing bloat.

Most of the work of being an owning reference can be done in the constructor, destructor, and assignment operators of nsCOMPtr. Whenever you `point' the nsCOMPtr at a different {{mediawiki.external('XP')}}COM object (by assignment or initialization), it must Release its old value, if any, and AddRef the new. At its own destructor time it must Release as well. nsCOMPtr only does exactly the work you would have done, if you always remembered to do the right thing.

Safety Features

Type Safeguards

It is an invariant of nsCOMPtr that it holds the {{mediawiki.external('XP')}}COM-correct interface pointer for it's underlying type. E.g., an nsCOMPtr<nsIFoo> will always hold the pointer that would be returned by QueryInterface, when querying an {{mediawiki.external('XP')}}COM object for its nsIFoo interface. In debug builds, if you subvert this invariant with one of the assignment forms that doesn't call QueryInterface, nsCOMPtr will assert at runtime in the bad assignment.

// Given two un-related interfaces |nsIFoo| and |nsIBar|...
nsIBar* bar = ...;
// ...

nsCOMPtr<nsIFoo> foo = bar;
  // NS_ASSERTION: "QueryInterface needed"

  // ...even assuming you can get the line to compile
  //  (either by casting, or because the types are related by C  )

This invariant is relaxed for nsCOMPtr<nsISupports>. Like nsISupports* (or even void*), people generally use nsCOMPtr<nsISupports> to mean `any {{mediawiki.external('XP')}}COM interface'. It would be annoying if nsCOMPtr forced you to QueryInterface to the {{mediawiki.external('XP')}}COM-correct nsISupports within an object in places where you don't care to know the exact type.

NULL-dereference Safeguards

An nsCOMPtr will also assert at runtime if you try to dereference it when it is void, e.g.,

nsCOMPtr<nsIFoo> foo;
  // Note: default initialized to |0|

foo->DoSomething();
  // NS_PRECONDITION: "You can't dereference a NULL nsCOMPtr with operator->()"

A similar precondition intervenes on behalf of operator*.

Reference-Counting Safeguards

All of the operations that extract the underlying raw pointer out of an nsCOMPtr use a C trick to implement another safety feature. The pointer returned cannot be AddRefed, Released, or deleted.

nsCOMPtr<nsIFoo> foo = ...;

foo->AddRef();     // Error: |AddRef| is private
delete foo.get();  // Error: |operator delete| is private
NS_RELEASE(foo);   // Error: |Release| is private

Of course, the most important safety feature provided by nsCOMPtr is that it AddRefs and Releases automatically at the appropriate times.

Casting

Never use old-style C/C casts on an nsCOMPtr. An old-style cast is guaranteed to compile, even if it can't do the right thing. Old-style casts degenerate into the equivalent of reinterpret_cast if no conversion is defined. Such a cast can easily by-pass nsCOMPtrs machinery, causing leaks, type mismatches, and other calamities.

// Old-style C/C   casts by-pass |nsCOMPtr|s machinery and cause leaks...

nsresult rv;
nsCOMPtr<nsIFoo> foo = ...;

// ...
rv = GetFoo( (nsIFoo**)&foo );
rv = GetFoo( &(nsIFoo*)foo );
  // Sure, they compile; but now you leak.

To help prevent this, we are trying to make the first form, above, illegal by making operator& private. See bug #59414.

Implementation Details and Debugging Machinery

Although it is a class, nsCOMPtr has no virtual methods, and therefore, no vtable or vptr. Because a few key routines are factored out into a common non-template base class, the actual underlying pointer is stored as an nsISupports* (except in debug builds where NSCAP_FEATURE_DEBUG_PTR_TYPES is turned on). It is because of these factored routines that nsCOMPtr users must link with the XPCOM library.

When NSCAP_FEATURE_DEBUG_PTR_TYPES is turned on, instead of holding its underlying pointer in a variable of type nsISupports*, the nsCOMPtr holds it in a pointer matching the underlying type. This allows source level debuggers to more easily `follow' the pointer. However, the routines that would normally be factored into a base class now must become template-specific inlines. There is no factored base class. This implies that the entire application must be compiled with the same setting of NSCAP_FEATURE_DEBUG_PTR_TYPES, else some parts will be expecting a base class and others will not. The app will not link.

Unit Tests

The unit tests for nsCOMPtr can be found in the file

Initialization and Assignment

Built-in forms

Assignment into, or initialization of an nsCOMPtr is easy to understand. The nsCOMPtr Releases its old value, if any, and then assigns in the new value, AddRefing it and/or calling QueryInterface as you direct by `annotating' the assignment with directives like dont_AddRef. This section describes each of the possibilities, though the directives can be more succinctly described in the {{mediawiki.external('#table_assignmentdirectives table below')}}.

You can construct an nsCOMPtr from, or assign into it any of the following

  • the value 0
  • another nsCOMPtr of the same type
  • a raw {{mediawiki.external('XP')}}COM interface pointer of the same type
  • a raw {{mediawiki.external('XP')}}COM interface pointer of the same type, annotated with the {{mediawiki.external('#quad1 <code>dont_QueryInterface</code>')}} directive
  • a raw {{mediawiki.external('XP')}}COM interface pointer of the same type, annotated with the {{mediawiki.external('#quad3 <code>dont_AddRef</code>')}} directive or a synonym
  • any interface pointer (either nsCOMPtr or a raw {{mediawiki.external('XP')}}COM interface pointer) of any type, annotated with the {{mediawiki.external('#quad2 <code>do_QueryInterface</code>')}} directive
  • a {{mediawiki.external('#ref_do_QueryReferent <code>do_QueryReferent</code>')}} directive

The first three of these are simple and obvious. The fourth (applying the dont_QueryInterface directive) is a synonym for just assigning in a raw {{mediawiki.external('XP')}}COM interface pointer of the same type. The remaining directives provide some additional control in special situations. Additionally, you can construct an nsCOMPtr without supplying an initial value, in which case it is initialized to 0. Just like a primitive pointer, an nsCOMPtr with the value 0 points to no object, and can be tested with expressions like if (foo) and if (!foo).

The directives mentioned above may make more sense in this table

Table 1. Options for assigning into an nsCOMPtr.
don't QI QI
AddRef

{{mediawiki.external('#quad1 T*,<br/><code>dont_QueryInterface(T*)</code>')}}

{{mediawiki.external('#quad2 <code>do_QueryInterface(nsISupports*)</code>, <br/><code>do_QueryInterface(nsISupports*, nsresult*)</code>')}} {{mediawiki.external('#ref_do_QueryReferent <code>do_QueryReferent(nsIWeakReference*)</code>, <br/><code>do_QueryReferent(nsIWeakReference*, nsresult*)</code>')}}

don't AddRef

{{mediawiki.external('#quad3 <code>dont_AddRef(T*)</code>,<br/><code>getter_AddRefs(T*)</code>')}}

{{mediawiki.external('#quad4 n/a')}}

E.g., one of the possibilities for assigning into an nsCOMPtr, but you don't want to AddRef the pointer you are assigning (because it has already been AddRefed for some reason) is dont_AddRef(T*) found at the intersection of "don't AddRef" and "don't QI". Here is a sample demonstrating the various positions these `annotations' can appear in, using dont_AddRef

// Controlling assignment into an |nsCOMPtr|...

  // in constructors...
nsCOMPtr<nsIFoo> foo1( dont_AddRef(rawFoo1Ptr) );
nsCOMPtr<nsIFoo> foo2 = dont_AddRef(rawFoo2Ptr);
   // Note that the function form (called `direct initialization') and the
  //  assignment form (called `copy initialization') of a constructor have
  //  subtly different meanings; prefer direct initialization.

nsCOMPtr<nsIFoo> foo3;

  // in a normal assignment...
foo3 = dont_AddRef(rawFoo3Ptr);
 
   // The annotations described in the table apply to both forms of constructor,
  //  and to plain-old assignment

Any of the annotations shown in the table can appear in all the positions demonstrated with dont_AddRef. The sections that follow describe each possibility.

nsCOMPtr<T> = T*,
nsCOMPtr<T> = dont_QueryInterface( T* )

The default behavior, shown in the table as T*, is to AddRef the new value, but not to call QueryInterface against it. This is what happens when no `annotation' is present, e.g.,

nsCOMPtr<nsIFoo> foo( aFooPtr ); // or
foo = aFooPtr;
  // ...will call |AddRef| but not |QueryInterface|

  // A more explicit synonym for this is...
nsCOMPtr<nsIFoo> foo( dont_QueryInterface(aFooPtr) ); // or
foo = dont_QueryInterface(aFooPtr);
 

By using this form, you are promising that the pointer you are assigning in is already a pointer to the {{mediawiki.external('XP')}}COM-correct interface matching the nsCOMPtrs underlying type, in this case, nsIFoo.

nsCOMPtr<T> = do_QueryInterface( nsISupports* ),
nsCOMPtr<T> = do_QueryInterface( nsISupports*, nsresult* )

If you can't satisfy the above promise, you can `annotate' the assignment to tell the nsCOMPtr it needs to call QueryInterface, e.g.,

nsCOMPtr<nsIFoo> foo( do_QueryInterface(aBarPtr) ); // or
foo = do_QueryInterface(aBarPtr);
   // ..._will_ call |QueryInterface| (and therefore, |AddRef|)

  // Of course, since you're calling |QueryInterface|, you might need the
  //  error result...
nsresult rv;
nsCOMPtr<nsIFoo> foo( do_QueryInterface(aBarPtr, &rv) ); // or
foo = do_QueryInterface(aBarPtr, &rv);
 
nsCOMPtr<T> = dont_AddRef( T* ),
nsCOMPtr<T> = getter_AddRefs( T* )

Sometimes, you happen to have a pointer lying around that's already AddRefed, but you want to put it into an nsCOMPtr. This often happens with getters that return the AddRefed pointer as their result (rather than an nsresult); or in the efficiency transformations. dont_AddRef is the perfect remedy to situations like this.

nsIFoo* temp;
nsresult rv = GetFoo(&temp);
nsCOMPtr<nsIFoo> foo( dont_AddRef(temp) );
  // |temp| has already been |AddRef|ed, but we want to manage it with an
  //  |nsCOMPtr|.

nsCOMPtr<nsIFoo> foo( getter_AddRefs(CreateAFoo()) );
  // |getter_AddRefs| is a synonym for |dont_AddRef| that may look better to
  //  you when applied to functions that return |AddRef|ed pointers

nsCOMPtr<nsIFoo> foo( dont_AddRef(CreateAFoo()) );
  // or, maybe you don't like it better...
nsCOMPtr<T> = /* call QueryInterface but don't AddRef */

You'll notice this quadrant of the table is marked `n/a'. There is no explicit directive that means "call QueryInterface, but don't AddRef the result". This option corresponds to the situation where you are calling a getter that returns an object of the wrong type. It has already AddRefed the object, so you don't want to, but you need to get a different interface out of it. Well, you can't have it. QueryInterface always AddRefs it's result, and there is no substitute for calling QueryInterface to get the right type. The solution is a two step process.

// ...

  // The getter returns an already |AddRef|ed object (of the wrong type)...
nsCOMPtr<nsIBar> bar( getter_AddRefs(CreateBar()) );
  // ...which I must query for the right type
nsCOMPtr<nsIFoo> foo( do_QueryInterface(bar) );

One unfortunate trap that people fall into in this case is forgetting that their getter function AddRefed the result. Which leads them to type in code that looks like this:

nsCOMPtr<nsIFoo> foo( do_QueryInterface(CreateBar()) );
  // Oops!  The interface returned by |CreateBar| leaks.
  //  You _must_ handle this case with the two step solution shown above.

  // Seems unlikely, you say?  You're more likely to see it in a form like this
nsCOMPtr<nsIFoo> foo( do_QueryInterface(aList->ElementAt(i)) );
  // |ElementAt|, like all good getters, |AddRefs| it's result
  //  which would be dropped on the floor, after querying it for the needed
  //  interface

Bugzilla bug# 8221 is specifically about finding and fixing this particular kind of leak.

nsCOMPtr helpers

nsCOMPtr<T> = do_QueryReferent( nsIWeakReference* ),
nsCOMPtr<T> = do_QueryReferent( nsIWeakReference*, nsresult* )

do_QueryReferent exists to facilitate weak references based on nsIWeakReference. An nsIWeakReference is an {{mediawiki.external('XP')}}COM object that acts as a proxy for another object. The nsIWeakReference and this other object have a special relationship. They know about each other, but neither holds an owning reference to the other. The two objects cooperate to ensure that neither ever holds a dangling pointer to the other. Holding an owning reference on the nsIWeakReference object allows you to get to this other object when you need to, but does not require it to go on living, just for you. To get to the object, you ask the nsIWeakReference object to QueryInterface it on your behalf. If the object still exists and supports the requested interface, you will (hopefully, temporarily) hold an owning reference to it.

nsIWeakReference* weakPtr = ...;

weakPtr->QueryReferent(

Using an nsCOMPtr<T> as a T*

Using an nsCOMPtr as a pointer

`In' Parameters

`Out' Parameters: getter_AddRefs

Assignment into an nsCOMPtr is fairly easy to understand. The nsCOMPtr Releases its old value, if any, and then assigns in the new value, AddRefing, and/or calling QueryInterface as you specified with the directives described above. These rules apply equally to the `assignment' that happens when copying parameters or function results that are declared to be nsCOMPtrs. If we want nsCOMPtrs to be a viable substitute for raw {{mediawiki.external('XP')}}COM interface pointers, however, we will need to deal with the issue of `out' parameters. Many {{mediawiki.external('XP')}}COM functions return interface pointers as results through parameters, e.g.,

// Getters can return interface pointers through `out' parameters...

nsresult GetFoo( nsIFoo** );     // a standard getter
nsresult GetFoo2( nsIFoo*& );    // a non-standard getter
nsresult GetSomething( void** ); // an `un-typed' getter
  // Note: |QueryInterface| is an example of a `un-typed' getter

We must be able to pass nsCOMPtrs by pointer or reference, into routines for use as `out' parameters. The problem is, that inside the getter there is no knowledge of nsCOMPtrs. It thinks it's getting a pointer (or a reference) to a raw {{mediawiki.external('XP')}}COM interface pointer. nsCOMPtrs smart assignment operators will not be called. The old value, if any, will be leaked.

This is where the getter_AddRefs( nsCOMPtr& ) comes in. getter_AddRefs Releases the old value, if any, clears it out, and returns a pointer to it, allowing the getter to fill in your nsCOMPtr with a new AddRefed value. We use getter_AddRefs as a sort of replacement for the & that we would apply to a raw {{mediawiki.external('XP')}}COM interface pointer in these situations. getter_AddRefs packages up all the magic we normally get from nsCOMPtrs constructors and assignment operators.

// raw [XP]COM interface pointers...

nsIFoo* foo;

GetFoo(&foo);
GetFoo2(foo);
GetSomething((void**)&foo);
// |nsCOMPtr|s...

nsCOMPtr<nsIFoo> foo;

GetFoo(getter_AddRefs(foo));
GetFoo2(*getter_AddRefs(foo));
GetSomething(getter_AddRefs(foo));

Why not just overload operator& to do this work? Several reasons: it would become inconvenient take the address of an nsCOMPtr in all other situations; the name `getter_AddRefs' enforces the notion that a certain behavior is required of the getter; and once upon a time, there was another possibility (as you're about to learn).

Is there a getter_doesnt_AddRef( nsCOMPtr& ) for getters that return non-AddRefed results through a parameter? No, there isn't. Once upon a time, there was, but it went away for three reasons:

  • It is against the rules of {{mediawiki.external('XP')}}COM for a getter to return a non-AddRefed interface pointer through a parameter (if you see it, report a bug).
  • getter_doesnt_AddRef had complex ramifications that ended up making nsCOMPtrs either bigger or slower than raw {{mediawiki.external('XP')}}COM interface pointers.
  • You can still call such a getter and put the result into an nsCOMPtr with a temporary, e.g.,
// Calling a getter that (illegally) doesn't |AddRef| its result...

nsIFoo* temp;
nsresult rv = GetFoo_WithoutAddRef(&temp);
   // Note to self: must report |GetFoo_WithoutAddRef| as a bug, all getters
  //  must |AddRef|
nsCOMPtr<nsIFoo> foo = temp;

`In/Out' Parameters

What about `in/out' parameters?

Efficiency and Correctness

The Costs of nsCOMPtr

nsCOMPtr is tuned to be a viable replacement for raw {{mediawiki.external('XP')}}COM interface pointers, anywhere you would use one as an owning reference. nsCOMPtrs performance is generally slightly more efficient that raw pointers in space, and negligably less efficient in time. Performance concerns should not deter you from using nsCOMPtr. The patterns presented throughout this section will help you get the most out of nsCOMPtr.

Space

In general, nsCOMPtr can be more efficient in space than using raw {{mediawiki.external('XP')}}COM pointers. This is primarily because it factors its destructor, and the more complicated constructors and assignment operators. By following the optimization tips in this section, you will write code that generates fewer bytes of object than you might with raw pointers. Even if you don't follow these suggestions, your nsCOMPtr code may still end up smaller, or at worst only negligable bulkier than the raw pointer version. See Code Bloat [LONG, summary at top] for details, though the recommendations from that document are re-iterated here.

Time

[[More time-performance measurements are needed.]]

In places where two or more subroutines calls are required, i.e., of AddRef, Release, and QueryInterface, some nsCOMPtr routines are factored, and hence, require additional time corresponding to invoking a subroutine. This time is negligable, especially in the face of work done by QueryInterface, and the work that may be done by Release.

In all other cases, nsCOMPtr does only the work you would have done by hand. The bulk of the work for which an nsCOMPtr is used is dereferencing with operator->, just as it is with a primitive pointer. On every platform, this operation generates the exact same code, and takes the same time, as performing this operation on a raw {{mediawiki.external('XP')}}COM interface pointer. The destructor, which corresponds to client code calling Release against a raw {{mediawiki.external('XP')}}COM interface pointer, is factored, requiring the extra time required to invoke a subroutine call, though this is balanced against the cost already present in both cases of calling Release which may, in turn, invoke delete and the referents destructor. All nsCOMPtrs constructors and assignment operators are inline. The simple constructors, i.e., those that don't query, do only exactly the same work that you would do by hand. Any routines that call more than one of AddRef, Release, or QueryInterface, are factored, and hence have the additional cost of invoking a subroutine call.

Only the fact that some routines are factored, thus introducing the overhead of an additional subroutine call, and that initialization cannot be by-passed, cause any extra run-time cost for nsCOMPtr over raw {{mediawiki.external('XP')}}COM interface pointers. Space and time trade-offs are finely balanced in nsCOMPtr. The factored routines are the direct result of bloat measurements.

Prefer Construction to Assignment

The most efficient way, in both time and space, to get a value into an nsCOMPtr is at construction time. Prefer construction over assignment whenever reasonable. Initialize member nsCOMPtrs in the member initialization clause of your constructor.

// Initialize member |nsCOMPtr|s in the member initialization clause of your
//  constructor...

class Bar
  {
    public:
      Bar( nsIFoo* initial_fooPtr );
      // ...
    private:
      nsCOMPtr<nsIFoo> mFooPtr;
  };

Bar::Bar( nsIFoo* initial_fooPtr )
    : mFooPtr(initial_fooPtr) // initialize it _here_
  {
    // not here
  }

Additionally, there is an optimization pattern using a temporary that converts assignment form to construction form.

// Default construction, followed by
//  assignment is not as efficient...

nsCOMPtr<nsIFoo> foo;
nsresult rv=GetFoo(getter_AddRefs(foo));





// ...as construction alone.

nsIFoo* temp;
nsresult rv=GetFoo(&temp);
nsCOMPtr<nsIFoo> foo=dont_AddRef(temp);

  // Remember this `raw-pointer, call
  //  getter, assign |dont_AddRef|'
  //  pattern.  It  crops up in many
  //  efficiency discussions.

In both cases you end up with foo, a valid nsCOMPtr whose value was set with the product of GetFoo, and rv the status returned by GetFoo. The case using the temporary, however, uses construction to put the value into the nsCOMPtr, which (though slightly more complicated in source) is more efficient than default construction followed by assignment, the course of events followed by the simpler example.

Prefer Destruction to Assignment

Prefer do_QueryInterface to calling QueryInterface

Iterating

There is a very common idiom for iterating over data-structures with normal pointers, e.g.,

// Iterating with pointers to non-[XP]COM objects...

Node* p = ...;
while ( p )
  {
    // ...
    p = p->next;
  }

One often sees this pattern expressed as a for loop, as well. Consider, however, what would happen if you were trying to do this with a raw {{mediawiki.external('XP')}}COM interface pointer.

// Iterating with raw [XP]COM interface pointers...

nsIDOMNode* p = ...;
while ( p )
  {
    // ...
    p->GetNext(&p);
      // Trouble!  We overwrote |p| without |Release|ing it.
  }

Oops! We just failed to Release p before putting a new pointer into it. People do this a lot, and it turns out to be a big source of leaks in normal {{mediawiki.external('XP')}}COM code. Well, could we do this instead?

// Iterating with raw [XP]COM interface pointers...

nsIDOMNode* p = ...;
while ( p )
  {
    // ...
    NS_RELEASE(p);
    p->GetNext(&p);
      // Trouble!  We tried to call a member function of a pointer
      //  that may be dangling or |NULL|.
  }

Unfortunately, not. After the Release, p could be dangling. In fact, if you used the NS_RELEASE macro, p would be NULL by the time you got to the GetNext call.

Now imagine that you've written the same thing with nsCOMPtr.

// Iterating with |nsCOMPtr|s...

nsCOMPtr<nsIDOMNode> p = ...;
while ( p )
  {
    // ...
    p->GetNext( getter_AddRefs(p) );
      // Trouble!  We tried to call a member function through a |NULL| pointer.
  }

Using nsCOMPtr is exactly like using raw {{mediawiki.external('XP')}}COM interface pointers, here. getter_AddRefs Releases and clears out p before you assign into it, i.e., before GetNext is called. Which means that by the time we get around to calling GetNext, we are trying to call it through a NULL pointer. Unlike raw {{mediawiki.external('XP')}}COM interface pointers, nsCOMPtr will fire an assert instead of blindly trying to call GetNext through a NULL pointer.

That's the problem. So what's the solution? If this were raw {{mediawiki.external('XP')}}COM interface pointers, we'd probably introduce a temporary. We can do the same thing with nsCOMPtr.

// Safe iterating with raw [XP]COM
//  interface pointers...

nsIDOMNode* p = ...;
while ( p )
  {
    // ...

      // Introduce a temporary so we
      //  don't stomp on |p|
    nsIDOMNode* temp = p;
    temp->GetNext(&p);
    NS_RELEASE(temp);
  }
// Safe iterating with |nsCOMPtr|...


nsCOMPtr<nsIDOMNode> p = ...;
while ( p )
  {
    // ...

      // Introduce a temporary so we
      //  don't stomp on |p|
    nsCOMPtr<nsIDOMNode> temp = p;
    temp->GetNext(getter_AddRefs(p));
  }

Although the nsCOMPtr parallel is easy to understand, it suffers from doing one extra AddRef and one extra Release compared to the raw pointer scheme. A slight transformation makes the code uglier, but (possibly negligably) more efficient.

// Safe, efficient, iterating with |nsCOMPtr|...

nsCOMPtr<nsIDOMNode> p = ...;
while ( p )
  {
    // ...
    nsIDOMNode* next;
    p->GetNext(&next);
    p = dont_AddRef(next);
  }

  // Look!  It's our friend, the `raw pointer, call getter, assign
  //  |dont_AddRef|' pattern.

Writing Getters

Compiler Annoyances

Frequently Asked Questions

This section will help you if you're fixing a broken build, or have what you think is a quick obvious question, and you don't have time to read the {{mediawiki.external('#reference_manual Reference Manual')}}. This FAQ usually just refers back directly to the appropriate answer, there. If you're looking here just to learn about nsCOMPtrs, you'll get a better introduction in the {{mediawiki.external('#users_guide Getting Started Guide')}}.

  • {{mediawiki.external('#FAQ_buildtime_errors Buildtime Errors')}}
  • {{mediawiki.external('#FAQ_runtime_errors Runtime Errors')}}
  • {{mediawiki.external('#FAQ_how_to How do I...')}}
  • {{mediawiki.external('#FAQ_general General')}}

The FAQ is divided into sections to help you find what you're looking for faster. In most cases, the answer will just refer back into the reference manual, above. No need to explain things twice :-).

Buildtime Errors

The build just broke. It's not in your code, or it's not on your platform, but there's an nsCOMPtr on the line where the error is and you're suspicious. You're looking in the right place.

comparing an nsCOMPtr to a raw [XP]COM interface pointer

declaring an nsCOMPtr to a forward-declared class

not linking to XPCOM

not including nsCOMPtr.h

different settings of NSCAP_FEATURE_DEBUG_PTR_TYPES

Runtime Errors

NS_ASSERTION "QueryInterface needed"

NS_PRECONDITION "You can't dereference a NULL nsCOMPtr with operator->()"

NS_PRECONDITION "You can't dereference a NULL nsCOMPtr with operator*()"

How do I...

initialize an nsCOMPtr?

Release an nsCOMPtr before it goes out of scope?

Assign 0 into it. Whenever an nsCOMPtr takes on a new value, it always Releases its old value, if any. Assigning in the value 0 is just like assigning in a raw pointer that happens to be NULL. The old referent will be Released. [See {{mediawiki.external('#ref_assignment Initialization and Assignment')}} for more details]

You should note, though, that there is a small performance penalty for this. The nsCOMPtr will still exercize logic in its destructor to attempt to Release the value it has at that time. The optimal solution is to arrange the lifetime of your nsCOMPtr to correspond to exactly how long you want to hold the reference. E.g., using blocks as in this sample

// The most efficient scheme is to scope your |nsCOMPtr| to live exactly as long
//  as you need to hold the reference

nsresult
SomeLongFunction( nsIBar* aBar )
  {
    nsresult rv;
    // ...

    {
      // I only need the |nsIFoo| interface for a short time
      //  so I control its lifetime by declaring it inside
      //  a block statement.

      nsCOMPtr<nsIFoo> foo( do_QueryInterface(aBar, &rv) );
      if ( foo )
        foo->DoSomeFooThing();

      // |foo| goes out of scope, and so |Release|s its referent, here
    }

    // ...tons of stuff here, during which I don't need an |nsIFoo|

    return rv;
  }

[[Move this discussion to the {{mediawiki.external('#ref_efficiency efficiency section')}}, and link to it from here.]]

make an nsCOMPtr leak (for a debug test)?

call a getter that uses a raw [XP]COM interface pointer as an `in/out' parameter?

call a getter that fills in an nsIFoo*& parameter?

call a getter that doesn't AddRef its result?

Any {{mediawiki.external('XP')}}COM function that returns an interface pointer, i.e., a `getter', must have already AddRefed that pointer. If it didn't, you should probably report it as a bug. No matter which code pattern you use to solve this problem, you should comment it, e.g., // Warning: this getter doesn't AddRef() its result. If the getter returns the new pointer as its function result, no worries,


General

Does nsCOMPtr bloat the code?

Are nsCOMPtrs fast? Can I use them in tight loops?

Bibliography

Web Resources

nsCOMPtr.h, and nsCOMPtr.cpp are the source to nsCOMPtr. You can examine the source to nsCOMPtr online using (the wonderful) LXR. Exploring this code is not an adventure for the faint of heart.

Some COM Ownership Guidelines.

Interface Pointers Considered Harmful by Don Box originally appeared in the September 1995 issue of "The C++ Report".

COM Smart Pointers Even More Harmful by Don Box is a follow-up article that originally appeared in the February 1996 issue of "The C++ Report".

Books

Essential COM by Don Box.

Effective COM by Don Box, et al.

The C++ Programming Language (3rd Edition) by Bjarne Stroustrup.

Effective C++ (2nd Edition): 50 Specific Ways to Improve Your Programs and Designs by Scott Meyers.

More Effective C++ : 35 New Ways to Improve Your Programs and Designs by Scott Meyers.

Effective C++ CD: 85 Specific Ways to Improve Your Programs and Designs by Scott Meyers.

People

Don Box is a smart guy who has been writing about COM programming for a long time.

Original Document Information

  • Author(s): Scott Collins
  • Last Updated Date: December 11, 2001
  • Copyright Information: Copyright © 1999, 2000 by the Mozilla organization; use is subject to the MPL. Portions of this content are © 1998–2007 by individual mozilla.org contributors; content available under a Creative Commons license | Details.

Revision Source

<p>This document is the sum total of everything written down about <code>nsCOMPtr</code>. If you have a question about <code>nsCOMPtr</code>, and this document doesn't answer it, there probably isn't a document that answers it. You'll have to turn to <a class="external" href="news:mozilla.dev.tech.xpcom">the XPCOM newgroup</a> or another experienced <code>nsCOMPtr</code> user, or find the answer by experimentation.
</p><p>If you've never used <code>nsCOMPtr</code> before, you're starting in the right place. Just keep reading. You'll know when to stop. After you've been using <code>nsCOMPtr</code>s for a while, and you reach unfamiliar territory, or run into compiler errors; you may want to return to this document to get help from the {{mediawiki.external('#Reference_Manual Reference Manual')}} or the {{mediawiki.external('#FAQ FAQ')}}.
</p>
<h2 name="Status.2C_Recent_Changes.2C_and_Plans"> Status, Recent Changes, and Plans </h2>
<div class="author-note">
<p>I'm sorry this section is in the way for first-time readers. You may want to skip ahead to the {{mediawiki.external('#contents table of contents')}}, or directly to the {{mediawiki.external('#Getting_Started_Guide Getting Started Guide')}}, the {{mediawiki.external('#Reference_Manual Reference Manual')}}, or the {{mediawiki.external('#FAQ FAQ')}}. I put this section at the top so that checking for recent changes will be easy.
</p>
</div>
<h3 name="Recent_changes_to_nsCOMPtr"> Recent changes to <code>nsCOMPtr</code> </h3>
<p>Most recent first
</p>
<ul><li> Made <code>==</code> and <code>!=</code> between an <code>nsCOMPtr</code> and a raw pointer (or a literal <code>0</code> or <code>nsnull</code>) work correctly on all compilers. See <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=65664">bug 65664</a>.
</li><li> Made {{mediawiki.external('#ref_getter_AddRefs &lt;code&gt;getter_AddRefs( nsCOMPtr&amp; )&lt;/code&gt;')}} apply the same {{mediawiki.external('#ref_assert_NoQueryNeeded type-safety check')}} that the simple assignment forms do.
</li><li> Added <code>do_CreateInstance</code>.
</li><li> Added <code>do_GetService</code>.
</li><li> Eliminated the need to cast <code>getter_AddRefs</code> when an <code>nsISupports**</code> is needed.
</li><li> Relaxed the invariant for <code>nsCOMPtr&lt;nsISupports&gt;</code>, so that it is now a pointer to any {{mediawiki.external('XP')}}COM interface.
</li><li> Added {{mediawiki.external('#ref_do_QueryReferent &lt;code&gt;do_QueryReferent&lt;/code&gt;')}} to make using <a class="external" href="http://www.mozilla.org/projects/xpcom/weak_references.html"><code>nsIWeakReference</code>s</a> easier.
</li></ul>
<h4 name="Plans_for_nsCOMPtr"> Plans for <code>nsCOMPtr</code> </h4>
<ul><li> bug <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59212"><span class="plain">#59212</span></a><span class="plain">: as soon as we test on more compilers, start recommending </span><code>already_AddRefed</code> as a function result.
</li><li> bug <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59414"><span class="plain">#59414</span></a><span class="plain">: making </span><code>operator&amp;</code> <code>private</code> may help prevent some {{mediawiki.external('#ref_casting leaks caused by casting')}}
</li><li> Move the factored <code>nsCOMPtr</code> routines into their own library, to reduce <code>nsCOMPtr</code> clients' dependency on the XPCOM library.
</li></ul>
<h4 name="Recent_changes_to_this_document"> Recent changes to this document </h4>
<ul><li> Removed the statement that <code><span class="plain">==</span></code> and <code><span class="plain">!=</span></code> between an <code>nsCOMPtr</code> and a raw pointer or literal 0 does not work on some compilers since it is no longer true.
</li><li> Added an entire section to the Getting Started Guide on {{mediawiki.external('#guide_nsCOMPtr_in_APIs &lt;code&gt;nsCOMPtr&lt;/code&gt;s in function signatures')}}
</li><li> Added references to recent bugs influencing the use of <code>nsCOMPtr</code> machinery: <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59212"><span class="plain">#59212</span></a>, and <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59414"><span class="plain">#59414</span></a>
</li><li> Fixed comparisons {{mediawiki.external('#comparison1 1')}} and {{mediawiki.external('#comparison3 3')}}, as per comments by Morten Welinder
</li><li> Updated examples to prefer direct initialization over copy initialization.
</li></ul>
<p><br>
</p>
<h2 name="Getting_Started_Guide"> Getting Started Guide </h2>
<p>If you have never used <code>nsCOMPtr</code>s before, this section is for you. If you're already familiar with <code>nsCOMPtr</code>s, then you might want to skip ahead to the {{mediawiki.external('#Reference_Manual Reference Manual')}} or the {{mediawiki.external('#FAQ FAQ')}}. Don't worry; the Getting Started Guide is short.
</p>
<h3 name="Introduction"> Introduction </h3>
<h4 name="What_is_nsCOMPtr.3F"> What is <code>nsCOMPtr</code>? </h4>
<p><code>nsCOMPtr</code> is a tool to help prevent leaks.
</p><p><code>nsCOMPtr</code> is a "smart pointer". It is a template class that acts, syntactically, just like an ordinary pointer in C or C++, i.e., you can apply <code>*</code> or <code>-&gt;</code> to it to "get to" what it points at. <code>nsCOMPtr</code> is smart in that, unlike a raw C++ pointer to an XPCOM object, <code>nsCOMPtr</code> manages <code>AddRef</code>, <code>Release</code>, and <code>QueryInterface</code> for you. <code>nsCOMPtr</code> is defined in the source files{{mediawiki.internal('#link_source &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}}:
</p>
<ul><li> <a class="external" href="http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsCOMPtr.h">xpcom/glue/nsCOMPtr.h</a>
</li><li> <a class="external" href="http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsCOMPtr.cpp">xpcom/glue/nsCOMPtr.cpp</a>
</li></ul>
<p>...though you probably don't want to look in there, just yet.
</p><p>With <code>nsCOMPtr</code>, you can write code that is shorter, cleaner, clearer, and safer, than you can with raw {{mediawiki.external('XP')}}COM interface pointers.
</p>
<h4 name=".5BXP.5DCOM_Basics:_Ownership_and_Reference_Counting"> [XP]COM Basics: Ownership and Reference Counting </h4>
<p>This is a quick refresher on some fundamental issues of {{mediawiki.external('XP')}}COM. You should already know this, and should be able to just skim this short section. If this is unfamiliar material, you're not ready for <code>nsCOMPtr</code>s yet. A good place to learn about the basic rules and reasoning behind COM is in <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201634465">Essential COM</a>{{mediawiki.internal('#link_essentialcom &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}} by <a class="external" href="http://www.develop.com/dbox/">Don Box</a>{{mediawiki.internal('#link_donbox &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}}. Don Box gets into more of the details, traps, and pitfalls of COM in <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201379686">Effective COM</a>{{mediawiki.internal('#link_effectivecom &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}}. You should also have a reasonable knowledge of C++. Probably the three most helpful books on this topic are <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201889544">The C Programming Language</a>{{mediawiki.internal('#link_cppprogramminglanguage &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}} by Bjarne Stroustrup, <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201924889">Effective C </a>{{mediawiki.internal('#link_effectivecpp &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}}, and <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/020163371X">More Effective C </a>{{mediawiki.internal('#link_moreeffectivecpp &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}} by Scott Meyers.
</p><p>All {{mediawiki.external('XP')}}COM objects are allocated on the heap. Clients don't get to know much about the implementation of any such object. They reference it only through a pointer to an `interface', i.e., the static type of the pointer is a pointer to an abstract base class, the actual object pointed to is a class derived from that abstract base class. The {{mediawiki.external('XP')}}COM object is said to `implement that interface'. The clients reference to the object is typically called `an interface pointer'.
</p><p>An object may implement many interfaces. Each interface is (at least conceptually) separately `reference counted'. That is, the interface keeps a count of the number of clients holding references to it. When that count goes to zero, the interface may <code>delete</code> itself. Clients are expected to keep this reference count accurate by incrementing it when they acquire a reference to the interface, and decrementing it before they let go. To facilitate this, all interfaces inherit from an abstract base class that provides the member functions <code>AddRef</code>, and <code>Release</code>.
</p><p>A rule of {{mediawiki.external('XP')}}COM is that any function that creates or returns an interface pointer will have already <code>AddRef</code>ed it. The caller can then hold onto the reference indefinitely, calling <code>Release</code> when it no longer needs it. When the last pointer to an interface is <code>Release</code>d, the interface (and consequently, typically the underlying object) will <code>delete</code> itself. As long as there is an outstanding <code>AddRef</code> against the interface, it continues to exist. If you forget to call <code>Release</code>, the object will leak, i.e., the storage for that object will never be reclaimed. Leaks are bad <code><span class="plain">:-)</span></code>.
</p><p>A reference through which you will call <code>AddRef</code> and <code>Release</code> is called an <b>owning reference</b>. It holds a stake in the underlying object. That object cannot go away until the owning reference has relinquished its claim. Not all references need to be owning references. In fact, if two objects somehow end up owning each other (even transitively) it becomes difficult for either of those object to be reclaimed without adding some `out-of-band' mechanism for breaking the ownership cycle. The document <a class="external" href="http://www.mozilla.org/projects/xpcom/Ownership.html">Some COM Ownership Guidelines</a>{{mediawiki.internal('#link_ownershipguidelines &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}} provides some hints on when ownership is needed. The following lists are good starting point, but by no means complete.
</p><p>You use an owning reference when
</p>
<ul><li> you created the object;
</li><li> you got the object from a function that <i>might</i> have created it, e.g., any `getter' function, such as <code>QueryInterface</code>, or <code>CreateInstance</code>. All good getters <code>AddRef</code> the interface pointers they produce, thus providing you with an owning reference;
</li><li> you will hold onto the reference longer than the scope of the function in which you acquired it, e.g., you got it as a parameter, but you're hanging onto it in a member variable [see, for example, {{mediawiki.external('#comparison1 Comparison 1')}}, below].
</li></ul>
<p>You don't need an owning reference when
</p>
<ul><li> the object is passed in as a parameter, and you <i>don't</i> need to keep it any longer than the scope of this function;
</li><li> the object's lifetime is known to contain yours in some well defined way, e.g., in the nodes of a tree, parent nodes keep owning references to their children, children need not keep owning references to their parents.
</li></ul>
<p>It turns out that reference counting by hand is hard for programmers to get right. It may sound simple, but in practice it's very easy to forget to <code>Release</code> at the appropriate moment. Or to <code>AddRef</code> too many or too few times.
</p>
<h4 name="How_does_nsCOMPtr_help.3F"> How does <code>nsCOMPtr</code> help? </h4>
<p><code>nsCOMPtr</code> manages <code>AddRef</code>, <code>Release</code>, and other red-tape for you. An <code>nsCOMPtr</code> looks and acts as much like a raw {{mediawiki.external('XP')}}COM interface pointer as C allows, but it knows it owns the object it points to. This takes a little getting used to on your part, but ends up with less typing, clearer, safer code, and less leaks.
</p><p>For instance, here is a typical snippet of code (at its most compact) where you assign a {{mediawiki.external('XP')}}COM interface pointer into a member variable, i.e., the body of a `setter' function, side-by-side using raw {{mediawiki.external('XP')}}COM interface pointers and <code>nsCOMPtr</code>s.
</p>
<table>
<caption align="bottom">Comparison 1. Setting a member variable.
</caption>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// raw [XP]COM interface pointers...</span>
<span class="comment">// given: |nsIFoo* mFooPtr;|</span>

<span class="comment"><span class="plain">/*
   |AddRef| the new value if it's not
   |NULL|; assign it in; and |Release|
   the old value, if any (so we don't
   leak it).
 
   This order of assignment is special
   and must be used to avoid particular
   ownership bugs.
 */</span></span>

<strong>NS_IF_ADDREF(aFooPtr);
nsIFoo* temp = mFooPtr;</strong>
mFooPtr = aFooPtr;
<strong>NS_IF_RELEASE(temp);</strong>
</pre>
</td><td>
<pre class="eval"><span class="comment">// |nsCOMPtr|...</span>
<span class="comment">// given: |nsCOMPtr&lt;nsIFoo&gt; mFooPtr;|</span>

<span class="comment"><span class="plain">/*
   This assignment automatically
   |Release|s the old value in
   |mFooPtr|, if any, and |AddRef|s the
   new one, in the appropriate sequence
   to avoid the ownership bug mentioned
   earlier.
 */</span></span>





mFooPtr = aFooPtr;

</pre>
</td></tr></tbody></table>
<p>Additionally, the class using raw {{mediawiki.external('XP')}}COM interface pointers will need a destructor to <code>Release</code> <code>mFooPtr</code><span class="plain">; and a constructor to ensure that </span><code>mFooPtr</code> is initially set to <code>NULL</code> (or some other reasonable value).
</p><p><code>nsCOMPtr</code> helps you write code that is leak-proof, exception safe, and significantly less verbose than you would with raw {{mediawiki.external('XP')}}COM interface pointers. With <code>nsCOMPtr</code>, you may never have to call <code>AddRef</code>, <code>Release</code>, or <code>QueryInterface</code> by hand.
</p><p>You still have to understand {{mediawiki.external('XP')}}COM. You still have to know which functions return interface pointers that have already been <code>AddRef</code>ed and which don't. You still have to ensure your program logic doesn't produce circularly referencing garbage. <code>nsCOMPtr</code> is not a panacea. It is, however, helpful, easy to use, well-tested, and polite. It doesn't require that a function author cooperate with you, nor does your use force others to use it.
</p>
<h3 name="Using_nsCOMPtr"> Using <code>nsCOMPtr</code> </h3>
<h4 name="The_Basics"> The Basics </h4>
<p>In most cases, you'll use an <code>nsCOMPtr</code> exactly as you would a raw {{mediawiki.external('XP')}}COM interface pointer. Note the slight difference in declaration.
</p>
<table>
<caption align="bottom">Comparison 2. Similarities: <code>nsCOMPtr</code> is syntactically similar to raw {{mediawiki.external('XP')}}COM interface pointers.
</caption>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// raw [XP]COM interface pointers...</span>

nsIFoo<strong><span class="plain">*</span></strong> fooPtr <strong><span class="plain">= 0</span></strong><span class="plain">;
 </span><span class="comment">// ...</span>
fooPtr-&gt;SomeFunction(x, y, z);
AnotherFunction(fooPtr);

if ( fooPtr )
  <span class="comment">// ...</span>

if ( fooPtr == foo2Ptr )
  <span class="comment">// ...</span>
</pre>
</td><td>
<pre class="eval"><span class="comment">// |nsCOMPtr|...</span>

<strong>nsCOMPtr&lt;</strong>nsIFoo<strong>&gt;</strong> fooPtr;
<span class="comment">// ...</span>
fooPtr-&gt;SomeFunction(x, y, z);
AnotherFunction(fooPtr);

if ( fooPtr )
  <span class="comment">// ...</span>

if ( fooPtr == foo2Ptr )
  <span class="comment">// ...</span>
</pre>
</td></tr></tbody></table>
<p>There are two main differences. First: you no longer need, nor are you allowed, to call <code>AddRef</code> or <code>Release</code>.
</p>
<table>
<caption align="bottom">Comparison 3. Differences: <code>AddRef</code> and <code>Release</code> are illegal for <code>nsCOMPtr</code>s.
</caption>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// raw [XP]COM interface pointers...</span>
<span class="comment">// given: |nsIFoo* mFooPtr;|</span>

  <span class="comment">/*
    Note: this sequence is not the
    correct order to do assign
    raw pointers anyway (see
    [#comparison1 Comparison 1]) but I need it
    for this comparison.
  */</span>

NS_IF_RELEASE(mFooPtr);

mFooPtr = aFooPtr;
NS_IF_ADDREF(mFooPtr);

</pre>
</td><td>
<pre class="eval"><span class="comment">// |nsCOMPtr|...</span>
<span class="comment">// given: |nsCOMPtr&lt;nsIFoo&gt; mFooPtr;|</span>

  <span class="comment">/*
    You no longer need, nor will the
    compiler let you, call |AddRef|,
    or |Release|.
  */</span>



<span class="warning">NS_IF_RELEASE(mFooPtr);</span>
  <span class="comment">// Error: |Release| is private</span>
mFooPtr = aFooPtr;
<span class="warning">NS_IF_ADDREF(mFooPtr);</span>
  <span class="comment">// Error: |AddRef| is private</span>
</pre>
</td></tr></tbody></table>
<p>Second: you can't just pass the address of an <code>nsCOMPtr</code> to a getter expecting to return a result through a raw {{mediawiki.external('XP')}}COM interface pointer parameter. You have to `annotate' the <code>nsCOMPtr</code> with the {{mediawiki.external('#ref_getter_AddRefs &lt;code&gt;getter_AddRefs&lt;/code&gt;')}} directive.
</p>
<table>
<caption align="bottom">Comparison 4. Differences: apply <code>getter_AddRefs</code> when using an <code>nsCOMPtr</code> as a `out parameter'.
</caption>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// raw [XP]COM interface pointers...</span>

nsIFoo* foo;

GetFoo(<strong>&amp;</strong>foo);
</pre>
</td><td>
<pre class="eval"><span class="comment">// |nsCOMPtr|s...</span>

nsCOMPtr&lt;nsIFoo&gt; foo;

GetFoo(<strong>getter_AddRefs(</strong>foo<strong>)</strong>);
</pre>
</td></tr></tbody></table>
<p>That's it. You now know enough to start using <code>nsCOMPtr</code>s. There are a few other details you will want to know as you use <code>nsCOMPtr</code> in more complicated situations, but what you've just learned will cover 90% of your uses.
</p>
<h4 name="A_Few_Details"> A Few Details </h4>
<p>There are a couple more things that will help you get the most out of <code>nsCOMPtr</code>.
</p><p>Very often, you first get an interface pointer by calling <code>QueryInterface</code>. <code>QueryInterface</code> is a getter like any other, and you already know one way to call it, applying the <code>getter_AddRefs</code> rule, as described above.
</p>
<table>
<caption align="bottom">The hard way to <code>QueryInterface</code> into an <code>nsCOMPtr</code>.
</caption>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// A way (though not the best way) to |QueryInterface| into an |nsCOMPtr|...</span>

nsCOMPtr&lt;nsIFoo&gt; foo;

nsresult rv = bar-&gt;QueryInterface(NS_GET_IID(nsIFoo), getter_AddRefs(foo));

  <span class="comment">// Or, if you're a savvy [XP]COM programmer,</span>
  <span class="comment">//  you use the type-safe version...</span>
nsresult rv = CallQueryInterface(bar, getter_AddRefs(foo));
</pre>
</td></tr></tbody></table>
<p><code>QueryInterface</code> is used so frequently, though, that <code>nsCOMPtr</code> has a special facility to call it. This facility is type-safe, and it enables an <code>nsCOMPtr</code> to be directly constructed from the result of <code>QueryInterface</code>. Construction from the correct value is more efficient that construction followed by assignment. This facility is the {{mediawiki.external('#quad2 &lt;code&gt;do_QueryInterface&lt;/code&gt;')}} directive. Using <code>do_QueryInterface</code>, the sample above would look like this
</p>
<table>
<caption align="bottom">How to <code>QueryInterface</code> into an <code>nsCOMPtr</code>.
</caption>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// The best way to |QueryInterface| into an |nsCOMPtr|...</span>

nsresult rv;
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">do_QueryInterface(</span>bar, &amp;rv<span class="notice">)</span> );

  <span class="comment">// Or, if you don't care about the |nsresult|</span>
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">do_QueryInterface(</span>bar<span class="notice">)</span> );
</pre>
</td></tr></tbody></table>
<p><code>nsCOMPtr</code> happily calls <code>AddRef</code> and <code>Release</code> implicitly. This same favor is <i>not</i> extended to <code>QueryInterface</code>. <code>nsCOMPtr</code> does not <code>QueryInterface</code> on assignment without your explicit permission in the form of the <code>do_QueryInterface</code> directive. You need never worry about hidden queries. However, be aware that if you <i>should</i> have queried but didn't, e.g., when assigning in a raw pointer where C allows the assignment, but {{mediawiki.external('XP')}}COM wouldn't, <code>nsCOMPtr</code> will {{mediawiki.external('#ref_assert_NoQueryNeeded assert at runtime')}}. Use <code>do_QueryInterface</code> whenever you assign in a pointer to a {{mediawiki.external('XP')}}COM interface of a different type, even if that type happens to derive from the base type of the <code>nsCOMPtr</code>
</p>
<table>
<caption align="bottom">Comparison 6. <code>do_QueryInterface</code> prevents {{mediawiki.external('XP')}}COM type errors.
</caption>
<tbody><tr>
<td>
<pre class="eval">class nsIBar
  : public nsIFoo ... { ... };

nsIBar* p = ...;

  <span class="comment">// C   thinks every |nsIBar*| is an</span>
  <span class="comment">//  |nsIFoo*|, therefore, C   allows</span>
  <span class="comment">//  this...</span>
nsCOMPtr&lt;nsIFoo&gt; <span class="warning">foo = p;</span>
  <span class="comment">//  ...even though it is an [XP]COM</span>
  <span class="comment">//  type error</span>
</pre>
</td><td>
<pre class="eval">class nsIBar
  : public nsIFoo ... { ... };

nsIBar* p = ...;



  <span class="comment">// No type error here...</span>
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">do_QueryInterface(</span>p<span class="notice">)</span> );


</pre>
</td></tr></tbody></table>
<p>Remember, the C type system and the {{mediawiki.external('XP')}}COM type system are really two independent things. Because {{mediawiki.external('XP')}}COM interfaces are expressed as abstract C base classes, you may be tempted to let C handle the differences, or to use C casts to navigate between interface types. This is wrong. The only sanctioned way to get between {{mediawiki.external('XP')}}COM types is with <code>QueryInterface</code>. In the example above, there is no reason to assume that the <code>nsIFoo*</code> C pulls out of <code>p</code> would be the same one that <code>p-&gt;QueryInterface()</code> would return.
</p><p>{{mediawiki.external('#quad3 &lt;code&gt;dont_AddRef&lt;/code&gt;')}} is a similar directive that helps you when you assign in a pointer that has already been <code>AddRef</code>ed, e.g., because you called a getter that returned the pointer as its function result.
</p>
<table>
<caption align="bottom">Using <code>dont_AddRef</code>.
</caption>
<tbody><tr>
<td>
<pre class="eval">nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">dont_AddRef(</span>CreateFoo()<span class="notice">)</span> );
  <span class="comment">// |CreateFoo| |AddRef|s its result, as all good getters do</span>
</pre>
</td></tr></tbody></table>
<h4 name="Something_nsCOMPtr_Doesn.27t_Do"> Something <code>nsCOMPtr</code> <i>Doesn't</i> Do </h4>
<p>An <code>nsCOMPtr</code> does all that is necessary to behave as an owning reference. A given <code>nsCOMPtr</code> does not, however, cooperate in making <i>other</i> owning pointers. After learning how <code>nsCOMPtr</code> automatically <code>AddRef</code>s a pointer as it is being assigned <i>in</i>, the natural assumption is that it does the same thing when assigning <i>out</i>. Here is a snippet of code that demonstrates this misconception.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Incorrect assumptions about |nsCOMPtr|...</span>

nsresult
nsCacheRecord::GetFileSpec( nsIFileSpec** aFileSpecResult )
    <span class="comment">/*
      ...fills in the callers |nsFileSpec*| (which the caller supplied
      the address of) with a copy of my member variable |mFileSpec|,
      an |nsCOMPtr|.  I.e., this function is a `getter'.

      Remember: good [XP]COM getters always |AddRef| their result.
    */</span>
  {
    <span class="comment">// ...</span>
    *aFileSpec = mFileSpec;
      <span class="warning"><span class="comment">// the |nsCOMPtr| should take care of the refcount here, right?</span></span>
    return NS_OK;
  }
</pre>
</td></tr></tbody></table>
<p>Plainly, the author believed (though perhaps with some question) that the <code>nsCOMPtr</code>, <code>mFileSpec</code>, would <code>AddRef</code> automatically as it was assigned into <code><span class="plain">*aFileSpec</span></code>. This is <i>not</i> the case. An <code>nsCOMPtr</code> automatically calls <code>AddRef</code> and <code>Release</code> (only) on its <i>own</i> behalf. In all other situations, it is designed to be a drop in replacement for a raw {{mediawiki.external('XP')}}COM pointer. Where ever an <code>nsCOMPtr</code> is used in a situation where a raw pointer is needed, the <code>nsCOMPtr</code> automatically provides one.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// |nsCOMPtr| produces a raw pointer when needed...</span>

nsCOMPtr&lt;nsIFoo&gt; foo = ...;

  <span class="comment">// 1.  Assigning into a raw pointer</span>
nsIFoo* raw_foo = foo;

  <span class="comment">// 2.  Assigning into another |nsCOMPtr|</span>
nsCOMPtr&lt;nsIFoo&gt; foo2 = foo;

  <span class="comment">// 3.  As a parameter</span>
SetFoo(foo);

  <span class="comment">// 4.  Testing the value in an |if| expression</span>
  <span class="comment">// 5.  Calling a member function</span>
if ( foo )
  foo-&gt;DoSomething();
</pre>
</td></tr></tbody></table>
<p>In all of these cases, pretty much the exact same code is executed (case 2 is slightly different, but the intent is the same). In each case, you are essentially extracting the raw pointer value for your own purpose. If the <code>nsCOMPtr</code> <code>AddRef</code>ed the value each time you did that, cases 4 and 5 would obviously always generate leaks. <code>SetFoo</code>, from case 3, would have to be written two different ways when given an <code>nsCOMPtr</code>, it would know the value was already <code>AddRef</code>ed, and when given a raw pointer it would assume the value was not <code>AddRef</code>ed. Actually the contradictions run deeper than that. All these cases show that automatically <code>AddRef</code>ing on `output' makes <code>nsCOMPtr</code>s and raw-pointers act differently from the point of view of the clients. The goal is to make them act the same so that <code>nsCOMPtr</code>s can be a drop in replacement (modulo managing its own `ownership').
</p><p>Given what you now know, the rule is predictable. As described above, and unless you tell it otherwise, an <code>nsCOMPtr</code> <code>AddRef</code>s when you assign <i>in</i> to it. It does nothing when you assign <i>out</i> of it.
</p>
<h4 name="Where_should_I_use_nsCOMPtrs.3F"> Where should I use <code>nsCOMPtr</code>s? </h4>
<p>You should use an <code>nsCOMPtr</code> any place you use an interface pointer as an owning reference, i.e., where you call <code>AddRef</code> and <code>Release</code> on it. You should use <code>nsCOMPtr</code> as a member variable, where it will simplify setters, and eliminate constructors, destructors, and assignment operators. You should use <code>nsCOMPtr</code> on the stack, where it makes calling <code>QueryInterface</code> almost pleasant, and eliminates the complex logic that falls out of error handling.
</p>
<h4 name="Where_shouldn.27t_I_use_nsCOMPtrs.3F"> Where shouldn't I use <code>nsCOMPtr</code>s? </h4>
<p>Don't use <code>nsCOMPtr</code>s where you don't need an owning reference. See <a class="external" href="http://www.mozilla.org/projects/xpcom/Ownership.html">Some COM Ownership Guidelines</a>{{mediawiki.internal('#link_ownershipguidelines &lt;span class=\"plain\"&gt;' .. # .. '&lt;/span&gt;', "en")}}. <code>nsCOMPtr</code> is designed to be used with {{mediawiki.external('XP')}}COM interfaces, so don't use it with non-interfaces with specific exceptions described {{mediawiki.external('#guide_nsCOMPtrs_for_concrete_classes below')}}. Don't use <code>nsCOMPtr</code>s in {{mediawiki.external('XP')}}COM interfaces. Don't use them in plain old C code; <code>nsCOMPtr</code>s are, of course, a C only construct. {{mediawiki.external('#ref_casting Never cast')}} an <code>nsCOMPtr</code>, it's almost guaranteed to leak.
</p>
<h4 name="nsCOMPtrs_for_non-interface_classes"> <code>nsCOMPtr</code>s for non-interface classes </h4>
<p>Appropriately formatted answer to come, in the meanwhile, the full details are available in <a class="external" href="news://news.mozilla.org/scc-3E1526.12182423042001@h-204-29-187-152.netscape.com">this news posting</a>.
</p>
<h4 name="nsCOMPtrs_in_function_signatures"> <code>nsCOMPtr</code>s in function signatures </h4>
<p>In general, you won't want to use <code>nsCOMPtr</code> in the signature of XPCOM (i.e., `scriptable') functions. <code>nsCOMPtr</code> is not currently directly supported by IDL. However, you may sometime be tempted to use an <code>nsCOMPtr</code> in a non-scriptable function.
</p>
<h5 name="nsCOMPtr.3CT.3E_f.28.29_don.27t_return_an_nsCOMPtr"> <span class="warning"><code>nsCOMPtr&lt;T&gt; f()</code></span> don't return an <code>nsCOMPtr</code> </h5>
<p>This practice is dangerous. Returning an <code>AddRef</code>ed pointer in almost any form as a function result leads to several potential errors, some of which are leaks, some of which are dangling pointers. Returning an <code>nsCOMPtr</code> may seem like a good idea (since it tells clients you are giving them ownership), however it can be the cause of an dangling pointer. Consider:
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Don't return |nsCOMPtr|s...</span>
nsCOMPtr&lt;nsIFoo&gt; CreateFoo();
<span class="comment">// ...</span>

<span class="warning">nsIFoo* myFoo = CreateFoo();</span> <span class="comment">// Oops: |myFoo| now dangles!</span>
  <span class="comment">// |CreateFoo| returns an |nsCOMPtr|, which</span>
  <span class="comment">//  automatically |Release|s right after this</span>
  <span class="comment">//  assignment.  Now |myFoo| refers to a</span>
  <span class="comment">//  deleted object.</span>
</pre>
</td></tr></tbody></table>
<p>You can tell callers you are giving them ownership in a way that doesn't pose this hazard by returning a <code>already_AddRefed&lt;T&gt;</code> (see bug <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59212"><span class="plain">#59212</span></a>). An <code>nsCOMPtr</code> knows not to <code>AddRef</code> a value that is <code>already_AddRefed</code>.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Preferred form: if you must return a pointer, use |already_AddRefed|...</span>
already_AddRefed&lt;nsIFoo&gt; CreateFoo();
<span class="comment">// ...</span>

nsIFoo* myFoo1 = CreateFoo(); <span class="comment">// doesn't dangle</span>
nsCOMPtr&lt;nsIFoo&gt; myFoo2( CreateFoo() ); <span class="comment">// doesn't leak</span>
nsCOMPtr&lt;nsIFoo&gt; myFoo3( dont_AddRef(CreateFoo()) ); <span class="comment">// redundant, but legal and correct</span>
</pre>
</td></tr></tbody></table>
<p>Compare this to the most frequent leaks caused by returning a raw pointer you have already <code>AddRef</code>ed:
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Don't return raw pointers; that incites leaks...</span>
nsIFoo* CreateFoo(); <span class="comment">// returns an |AddRef|ed pointer</span>
<span class="comment">// ...</span>

<span class="warning">nsCOMPtr&lt;nsIFoo&gt; myFoo = CreateFoo();</span> <span class="comment">// Oops: leak;</span>
nsCOMPtr&lt;nsIFoo&gt; myFoo( <span class="notice">dont_AddRef(</span>CreateFoo()<span class="notice">)</span> );
  <span class="comment">// Since |CreateFoo| already |AddRef|s its result, we must remind</span>
  <span class="comment">//  our |nsCOMPtr| not to.  It's easy to forget.  Prevent it in advance</span>
  <span class="comment">//  by not returning pointers as function results, or else by returning</span>
  <span class="comment">//  an |already_AddRefed&lt;T&gt;| as above.</span>
</pre>
</td></tr></tbody></table>
<h5 name="void_f.28_nsCOMPtr.3CT.3E_.29_don.27t_pass_an_nsCOMPtr_by_value"> <span class="warning"><code>void f( nsCOMPtr&lt;T&gt; )</code></span> don't pass an <code>nsCOMPtr</code> by value </h5>
<p>This practice is wasteful, but not otherwise harmful. There is no need to <code>AddRef</code> parameters, as they are guaranteed to live as long as the function call. You only need to <code>AddRef</code> them as you store them in a structure that will live longer than the function call. Which means the appropriate member of that structure should be an <code>nsCOMPtr</code>, not the function parameter. Additionally, this signature may confuse callers into thinking they need an <code>nsCOMPtr</code> just to call the function.
</p>
<h5 name="void_f.28_const_nsCOMPtr.3CT.3E&amp;_.29_don.27t_pass_an_nsCOMPtr_by_const_reference"> <span class="warning"><code>void f( const nsCOMPtr&lt;T&gt;&amp; )</code></span> don't pass an <code>nsCOMPtr</code> by <code>const</code> reference </h5>
<p>Exactly as the signature above, this practice is wasteful, but not otherwise harmful, and has the same impact as passing an <code>nsCOMPtr</code> by value if the caller only supplied a raw pointer.
</p>
<h5 name="void_f.28_nsCOMPtr.3CT.3E.2A_.29_avoid_passing_an_nsCOMPtr_by_address.2C_if_possible"> <span class="warning"><code>void f( nsCOMPtr&lt;T&gt;* )</code></span> avoid passing an <code>nsCOMPtr</code> by address, if possible </h5>
<p>This practice requires callers to have an <code>nsCOMPtr</code>, and requires them to do a little extra work, as <code>operator&amp;</code> for <code>nsCOMPtr</code>s is <code>private</code> (to help prevent {{mediawiki.external('#ref_casting leaks caused by casting')}}<span class="plain">; also see bug </span><a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59414"><span class="plain">#59414</span></a>). This is an acceptable way to declare `in/out' parameters, but prefer passing <code>nsCOMPtr</code>s by reference, as below.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Passing an |nsCOMPtr| by pointer requires extra work...</span>
void f( nsCOMPtr&lt;nsIFoo&gt;* );
<span class="comment">// ...</span>

nsCOMPtr&lt;nsIFoo&gt; myFoo = ...;

f( <span class="notice">address_of(</span>myFoo<span class="notice">)</span> );
</pre>
</td></tr></tbody></table>
<h5 name="void_f.28_nsCOMPtr.3CT.3E&amp;_.29_do_pass_an_nsCOMPtr_by_reference_for_.60in.2Fout.27_parameters"> <span class="notice"><code>void f( nsCOMPtr&lt;T&gt;&amp; )</code></span> do pass an <code>nsCOMPtr</code> by reference for `in/out' parameters </h5>
<p>This is the prefered scheme for providing `in/out' parameters. If you were to use a raw pointer instead, your function couldn't know what ownership relationship the caller had to the input value, and hence, couldn't know whether to <code>Release</code> it or not before assigning in the new value. By declaring the parameter as an <code>nsCOMPtr&amp;</code>, the relationship is explicit.
</p>
<h3 name="Summary"> Summary </h3>
<p>An <code>nsCOMPtr</code> is an owning reference. Whatever it points to has been <code>AddRef</code>ed, counting the <code>nsCOMPtr</code> as one of its `owners'. An <code>nsCOMPtr</code> always calls <code>Release</code> before letting go, whether the <code>nsCOMPtr</code> is letting go so that it can point to a different object, or because the <code>nsCOMPtr</code> is going out of scope. Any time a new value is assigned into an <code>nsCOMPtr</code>, the <code>nsCOMPtr</code> automatically always <code>Release</code>s its old referent, if any, and (unless you tell it you already have) <code>AddRef</code>s the new.
</p><p>You use an <code>nsCOMPtr</code> exactly as you would a raw {{mediawiki.external('XP')}}COM interface pointer in almost all cases [though note the compiler problems shown in {{mediawiki.external('#comparison5 Comparison 5')}}]. You won't have to explictly call <code>AddRef</code> or <code>Release</code> through it, nor will the compiler allow it. The only place you can't use an <code>nsCOMPtr</code> without change is where a raw {{mediawiki.external('XP')}}COM interface pointer is an `out' parameter. In this case, you wrap the <code>nsCOMPtr</code> with {{mediawiki.external('#ref_getter_AddRefs &lt;code&gt;getter_AddRefs&lt;/code&gt;')}} [see {{mediawiki.external('#comparison4 Comparison 4')}}].
</p><p>When assigning into an <code>nsCOMPtr</code>, you will usually just supply another pointer (either a raw {{mediawiki.external('XP')}}COM interface pointer or an <code>nsCOMPtr</code>), with no additional directives [see, e.g., the <code>nsCOMPtr</code> side of {{mediawiki.external('#comparison1 Comparison 1')}}]. As stated above, with no directives, the <code>nsCOMPtr</code> will <code>Release</code> its old referent, if any, and <code>AddRef</code> the new. This is appropriate when the thing you're assigning in hasn't yet been <code>AddRef</code>ed to account for the new reference. This is typically the case when you are assigning in a pointer that you <i>didn't</i> call a function to get, e.g., one that was passed in as a parameter, or that you pulled out of a structure.
</p><p>You can tell <code>nsCOMPtr</code> it doesn't need to <code>AddRef</code> the new value on assignment by wrapping the new value in {{mediawiki.external('#quad3 &lt;code&gt;dont_AddRef&lt;/code&gt;')}}. Do this, for example, when you got the new value from a function which, like all good {{mediawiki.external('XP')}}COM getters, already called <code>AddRef</code> on your behalf.
</p><p>You may not assign in a pointer to a different interface type; you must first query it to the right type [see, e.g., {{mediawiki.external('#comparison6 Comparison 6.')}} and the surrounding discussion]. <code>nsCOMPtr</code> <i>never</i> calls <code>QueryInterface</code> implicitly, i.e., you must call it yourself, or explictly ask <code>nsCOMPtr</code> to call it with {{mediawiki.external('#quad2 &lt;code&gt;do_QueryInterface&lt;/code&gt;')}}. The <code>do_QueryInterface</code> directive allows you to do the query as part of the assignment. This better facilitates constructing an <code>nsCOMPtr</code> directly from the right value, rather than constructing it and assigning in the correct value later. Construction alone is more efficient than construction followed by assignment. Prefer construction over assignment whereever reasonable. Be careful not to apply <code>do_QueryInterface</code> to a function returning an <code>AddRef</code>ed pointer [see {{mediawiki.external('#quad4 this short section')}} for an explanation]
</p><p>For more details, continue on to the {{mediawiki.external('#reference_manual Reference Manual')}}.
</p>
<hr>
<h2 name="Reference_Manual"> Reference Manual </h2>
<div class="author-note">
<p>This section will help you if you're already familiar with <code>nsCOMPtr</code> but you need details. If you've never use <code>nsCOMPtr</code>s before, you might want to read the {{mediawiki.external('#users_guide Getting Started Guide')}} first. If you're trying to fix a broken build, the {{mediawiki.external('#FAQ FAQ')}} might lead you to the answer more quickly.
</p>
</div><div class="contents">
<ul><li> {{mediawiki.external('#ref_basics Tbe Basics')}}
</li><li> {{mediawiki.external('#ref_assignment Intitialization and Assignment')}}
</li><li> {{mediawiki.external('#ref_parameters Using an &lt;code&gt;nsCOMPtr&lt;T&gt;&lt;/code&gt; as a &lt;code&gt;T*&lt;/code&gt;')}}
</li><li> {{mediawiki.external('#ref_efficiency Efficiency and Correctness')}}
</li><li> {{mediawiki.external('#ref_annoyances Compiler Annoyances')}}
</li></ul>
</div>
<h3 name="The_Basics_2"> The Basics </h3>
<h4 name="Design"> Design </h4>
<p>An <code>nsCOMPtr</code> is designed to be a complete replacement for raw {{mediawiki.external('XP')}}COM interface pointers where they are used as owning references. Almost any place you could use a raw {{mediawiki.external('XP')}}COM interface pointer, you should be able to use an <code>nsCOMPtr</code>. An <code>nsCOMPtr</code> is the exact same size and shape as a raw {{mediawiki.external('XP')}}COM interface pointer. It can be used as a member variable without introducing bloat.
</p><p>Most of the work of being an owning reference can be done in the constructor, destructor, and assignment operators of <code>nsCOMPtr</code>. Whenever you `point' the <code>nsCOMPtr</code> at a different {{mediawiki.external('XP')}}COM object (by assignment or initialization), it must <code>Release</code> its old value, if any, and <code>AddRef</code> the new. At its own destructor time it must <code>Release</code> as well. <code>nsCOMPtr</code> only does exactly the work you would have done, if you always remembered to do the right thing.
</p>
<h4 name="Safety_Features"> Safety Features </h4>
<h5 name="Type_Safeguards"> Type Safeguards </h5>
<p>It is an invariant of <code>nsCOMPtr</code> that it holds the {{mediawiki.external('XP')}}COM-correct interface pointer for it's underlying type. E.g., an <code>nsCOMPtr&lt;nsIFoo&gt;</code> will always hold the pointer that would be returned by <code>QueryInterface</code>, when querying an {{mediawiki.external('XP')}}COM object for its <code>nsIFoo</code> interface. In debug builds, if you subvert this invariant with one of the assignment forms that doesn't call <code>QueryInterface</code>, <code>nsCOMPtr</code> will assert at runtime in the bad assignment.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Given two un-related interfaces |nsIFoo| and |nsIBar|...</span>
nsIBar* bar = ...;
<span class="comment">// ...</span>

<span class="warning">nsCOMPtr&lt;nsIFoo&gt; foo = bar;</span>
  <span class="comment">// NS_ASSERTION: "QueryInterface needed"</span>

  <span class="comment">// ...even assuming you can get the line to compile</span>
  <span class="comment">//  (either by casting, or because the types are related by C  )</span>
</pre>
</td></tr></tbody></table>
<p>This invariant is relaxed for <code>nsCOMPtr&lt;nsISupports&gt;</code>. Like <code>nsISupports*</code> (or even <code>void*</code>), people generally use <code>nsCOMPtr&lt;nsISupports&gt;</code> to mean `any {{mediawiki.external('XP')}}COM interface'. It would be annoying if <code>nsCOMPtr</code> forced you to <code>QueryInterface</code> to the {{mediawiki.external('XP')}}COM-correct <code>nsISupports</code> within an object in places where you don't care to know the exact type.
</p>
<h5 name="NULL-dereference_Safeguards"> <code>NULL</code>-dereference Safeguards </h5>
<p>An <code>nsCOMPtr</code> will also assert at runtime if you try to dereference it when it is void, e.g.,
</p>
<table>
<tbody><tr>
<td>
<pre class="eval">nsCOMPtr&lt;nsIFoo&gt; foo;
  <span class="comment">// Note: default initialized to |0|</span>

<span class="warning">foo-&gt;DoSomething();</span>
  <span class="comment">// NS_PRECONDITION: "You can't dereference a NULL nsCOMPtr with operator-&gt;()"</span>
</pre>
</td></tr></tbody></table>
<p>A similar precondition intervenes on behalf of <code>operator*</code>.
</p>
<h5 name="Reference-Counting_Safeguards"> Reference-Counting Safeguards </h5>
<p>All of the operations that extract the underlying raw pointer out of an <code>nsCOMPtr</code> use a C trick to implement another safety feature. The pointer returned cannot be <code>AddRef</code>ed, <code>Release</code>d, or <code>delete</code>d.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval">nsCOMPtr&lt;nsIFoo&gt; foo = ...;

<span class="warning">foo-&gt;AddRef();</span>     <span class="comment">// Error: |AddRef| is private</span>
<span class="warning">delete foo.get();</span>  <span class="comment">// Error: |operator delete| is private</span>
<span class="warning">NS_RELEASE(foo);</span>   <span class="comment">// Error: |Release| is private</span>
</pre>
</td></tr></tbody></table>
<p>Of course, the most important safety feature provided by <code>nsCOMPtr</code> is that it <code>AddRef</code>s and <code>Release</code>s automatically at the appropriate times.
</p>
<h4 name="Casting"> Casting </h4>
<p>Never use old-style C/C casts on an <code>nsCOMPtr</code>. An old-style cast is guaranteed to compile, even if it can't do the right thing. Old-style casts degenerate into the equivalent of <code>reinterpret_cast</code> if no conversion is defined. Such a cast can easily by-pass <code>nsCOMPtr</code>s machinery, causing leaks, type mismatches, and other calamities.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Old-style C/C   casts by-pass |nsCOMPtr|s machinery and cause leaks...</span>

nsresult rv;
nsCOMPtr&lt;nsIFoo&gt; foo = ...;

<span class="comment">// ...</span>
rv = GetFoo( <span class="warning">(nsIFoo**)&amp;foo</span> );
rv = GetFoo( <span class="warning">&amp;(nsIFoo*)foo</span> );
  <span class="comment">// Sure, they compile; but now you leak.</span>
</pre>
</td></tr></tbody></table>
<p>To help prevent this, we are trying to make the first form, above, illegal by making <code>operator&amp;</code> <code>private</code>. See bug <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59414"><span class="plain">#59414</span></a>.
</p>
<h4 name="Implementation_Details_and_Debugging_Machinery"> Implementation Details and Debugging Machinery </h4>
<p>Although it is a class, <code>nsCOMPtr</code> has no virtual methods, and therefore, no vtable or vptr. Because a few key routines are factored out into a common non-template base class, the actual underlying pointer is stored as an <code>nsISupports*</code> (except in debug builds where <code>NSCAP_FEATURE_DEBUG_PTR_TYPES</code> is turned on). It is because of these factored routines that <code>nsCOMPtr</code> users must link with the XPCOM library.
</p><p>When <code>NSCAP_FEATURE_DEBUG_PTR_TYPES</code> is turned on, instead of holding its underlying pointer in a variable of type <code>nsISupports*</code>, the <code>nsCOMPtr</code> holds it in a pointer matching the underlying type. This allows source level debuggers to more easily `follow' the pointer. However, the routines that would normally be factored into a base class now must become template-specific inlines. There is no factored base class. This implies that the entire application must be compiled with the same setting of <code>NSCAP_FEATURE_DEBUG_PTR_TYPES</code>, else some parts will be expecting a base class and others will not. The app will not link.
</p>
<h4 name="Unit_Tests"> Unit Tests </h4>
<p>The unit tests for <code>nsCOMPtr</code> can be found in the file
</p>
<ul><li> <a class="external" href="http://lxr.mozilla.org/seamonkey/source/xpcom/tests/TestCOMPtr.cpp">xpcom/tests/TestCOMPtr.cpp</a>
</li></ul>
<h3 name="Initialization_and_Assignment"> Initialization and Assignment </h3>
<h4 name="Built-in_forms"> Built-in forms </h4>
<p>Assignment into, or initialization of an <code>nsCOMPtr</code> is easy to understand. The <code>nsCOMPtr</code> <code>Release</code>s its old value, if any, and then assigns in the new value, <code>AddRef</code>ing it and/or calling <code>QueryInterface</code> as you direct by `annotating' the assignment with directives like <code>dont_AddRef</code>. This section describes each of the possibilities, though the directives can be more succinctly described in the {{mediawiki.external('#table_assignmentdirectives table below')}}.
</p><p>You can construct an <code>nsCOMPtr</code> from, or assign into it any of the following
</p>
<ul><li> the value <code>0</code>
</li><li> another <code>nsCOMPtr</code> of the same type
</li><li> a raw {{mediawiki.external('XP')}}COM interface pointer of the same type
</li><li> a raw {{mediawiki.external('XP')}}COM interface pointer of the same type, annotated with the {{mediawiki.external('#quad1 &lt;code&gt;dont_QueryInterface&lt;/code&gt;')}} directive
</li><li> a raw {{mediawiki.external('XP')}}COM interface pointer of the same type, annotated with the {{mediawiki.external('#quad3 &lt;code&gt;dont_AddRef&lt;/code&gt;')}} directive or a synonym
</li><li> any interface pointer (either <code>nsCOMPtr</code> or a raw {{mediawiki.external('XP')}}COM interface pointer) of any type, annotated with the {{mediawiki.external('#quad2 &lt;code&gt;do_QueryInterface&lt;/code&gt;')}} directive
</li><li> a {{mediawiki.external('#ref_do_QueryReferent &lt;code&gt;do_QueryReferent&lt;/code&gt;')}} directive
</li></ul>
<p>The first three of these are simple and obvious. The fourth (applying the <code>dont_QueryInterface</code> directive) is a synonym for just assigning in a raw {{mediawiki.external('XP')}}COM interface pointer of the same type. The remaining directives provide some additional control in special situations. Additionally, you can construct an <code>nsCOMPtr</code> without supplying an initial value, in which case it is initialized to <code>0</code>. Just like a primitive pointer, an <code>nsCOMPtr</code> with the value <code>0</code> points to no object, and can be tested with expressions like <code>if (foo)</code> and <code>if (!foo)</code>.
</p><p>The directives mentioned above may make more sense in this table
</p>
<table>
<caption align="bottom"> Table 1. Options for assigning into an <code>nsCOMPtr</code>.
</caption>
<tbody><tr>
<td>
</td><td> don't QI
</td><td> QI
</td></tr>
<tr>
<td> <code>AddRef</code>
</td><td bgcolor="#dddddd">
<p>{{mediawiki.external('#quad1 T*,&lt;br/&gt;&lt;code&gt;dont_QueryInterface(T*)&lt;/code&gt;')}}
</p>
</td><td bgcolor="#dddddd">
<p>{{mediawiki.external('#quad2 &lt;code&gt;do_QueryInterface(nsISupports*)&lt;/code&gt;, &lt;br/&gt;&lt;code&gt;do_QueryInterface(nsISupports*, nsresult*)&lt;/code&gt;')}} {{mediawiki.external('#ref_do_QueryReferent &lt;code&gt;do_QueryReferent(nsIWeakReference*)&lt;/code&gt;, &lt;br/&gt;&lt;code&gt;do_QueryReferent(nsIWeakReference*, nsresult*)&lt;/code&gt;')}}
</p>
</td></tr>
<tr>
<td> don't <code>AddRef</code>
</td><td bgcolor="#dddddd">
<p>{{mediawiki.external('#quad3 &lt;code&gt;dont_AddRef(T*)&lt;/code&gt;,&lt;br/&gt;&lt;code&gt;getter_AddRefs(T*)&lt;/code&gt;')}}
</p>
</td><td bgcolor="#dddddd">
<p>{{mediawiki.external('#quad4 n/a')}}
</p>
</td></tr></tbody></table>
<p>E.g., one of the possibilities for assigning into an <code>nsCOMPtr</code>, but you don't want to <code>AddRef</code> the pointer you are assigning (because it has already been <code>AddRef</code>ed for some reason) is <code>dont_AddRef(T*)</code> found at the intersection of "don't <code>AddRef</code>" and "don't QI". Here is a sample demonstrating the various positions these `annotations' can appear in, using <code>dont_AddRef</code>
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Controlling assignment into an |nsCOMPtr|...</span>

  <span class="comment">// in constructors...</span>
nsCOMPtr&lt;nsIFoo&gt; foo1( <span class="notice">dont_AddRef(</span>rawFoo1Ptr<span class="notice">)</span> );
nsCOMPtr&lt;nsIFoo&gt; foo2 = <span class="notice">dont_AddRef(</span>rawFoo2Ptr<span class="notice">)</span><span class="plain">;
   </span><span class="comment">// Note that the function form (called `direct initialization') and the</span>
  <span class="comment">//  assignment form (called `copy initialization') of a constructor have</span>
  <span class="comment">//  subtly different meanings; prefer direct initialization.</span>

nsCOMPtr&lt;nsIFoo&gt; foo3;

  <span class="comment">// in a normal assignment...</span>
foo3 = <span class="notice">dont_AddRef(</span>rawFoo3Ptr<span class="notice">)</span><span class="plain">;
 
   </span><span class="comment">// The annotations described in the table apply to both forms of constructor,</span>
  <span class="comment">//  and to plain-old assignment</span>
</pre>
</td></tr></tbody></table>
<p>Any of the annotations shown in the table can appear in all the positions demonstrated with <code>dont_AddRef</code>. The sections that follow describe each possibility.
</p>
<h5 name="nsCOMPtr.3CT.3E_.3D_T.2A.2CnsCOMPtr.3CT.3E_.3D_dont_QueryInterface.28_T.2A_.29"> <code>nsCOMPtr&lt;T&gt; = T*</code>,<br><code>nsCOMPtr&lt;T&gt; = dont_QueryInterface( T* )</code> </h5>
<p>The default behavior, shown in the table as <code>T*</code>, is to <code>AddRef</code> the new value, but not to call <code>QueryInterface</code> against it. This is what happens when no `annotation' is present, e.g.,
</p>
<table>
<tbody><tr>
<td>
<pre class="eval">nsCOMPtr&lt;nsIFoo&gt; foo( aFooPtr ); <span class="comment">// or</span>
foo = aFooPtr;
  <span class="comment">// ...will call |AddRef| but not |QueryInterface|</span>

  <span class="comment">// A more explicit synonym for this is...</span>
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">dont_QueryInterface(</span>aFooPtr<span class="notice">)</span> ); <span class="comment">// or</span>
foo = <span class="notice">dont_QueryInterface(</span>aFooPtr<span class="notice">)</span><span class="plain">;
 </span>
</pre>
</td></tr></tbody></table>
<p>By using this form, you are promising that the pointer you are assigning in is already a pointer to the {{mediawiki.external('XP')}}COM-correct interface matching the <code>nsCOMPtr</code>s underlying type, in this case, <code>nsIFoo</code>.
</p>
<h5 name="nsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A_.29.2CnsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A.2C_nsresult.2A_.29"> <code>nsCOMPtr&lt;T&gt; = do_QueryInterface( nsISupports* )</code>,<br><code>nsCOMPtr&lt;T&gt; = do_QueryInterface( nsISupports*, nsresult* )</code> </h5>
<p>If you can't satisfy the above promise, you can `annotate' the assignment to tell the <code>nsCOMPtr</code> it needs to call <code>QueryInterface</code>, e.g.,
</p>
<table>
<tbody><tr>
<td>
<pre class="eval">nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">do_QueryInterface(</span>aBarPtr<span class="notice">)</span> ); <span class="comment">// or</span>
foo = <span class="notice">do_QueryInterface(</span>aBarPtr<span class="notice">)</span><span class="plain">;
   </span><span class="comment">// ..._will_ call |QueryInterface| (and therefore, |AddRef|)</span>

  <span class="comment">// Of course, since you're calling |QueryInterface|, you might need the</span>
  <span class="comment">//  error result...</span>
nsresult rv;
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">do_QueryInterface(</span>aBarPtr<span class="notice">, &amp;rv)</span> ); <span class="comment">// or</span>
foo = <span class="notice">do_QueryInterface(</span>aBarPtr<span class="notice">, &amp;rv)</span><span class="plain">;
 </span>
</pre>
</td></tr></tbody></table>
<h5 name="nsCOMPtr.3CT.3E_.3D_dont_AddRef.28_T.2A_.29.2CnsCOMPtr.3CT.3E_.3D_getter_AddRefs.28_T.2A_.29"> <code>nsCOMPtr&lt;T&gt; = dont_AddRef( T* )</code>,<br><code>nsCOMPtr&lt;T&gt; = getter_AddRefs( T* )</code> </h5>
<p>Sometimes, you happen to have a pointer lying around that's already <code>AddRef</code>ed, but you want to put it into an <code>nsCOMPtr</code>. This often happens with getters that return the <code>AddRef</code>ed pointer as their result (rather than an <code>nsresult</code>); or in the efficiency transformations. <code>dont_AddRef</code> is the perfect remedy to situations like this.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval">nsIFoo* temp;
nsresult rv = GetFoo(&amp;temp);
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">dont_AddRef(</span>temp<span class="notice">)</span> );
  <span class="comment">// |temp| has already been |AddRef|ed, but we want to manage it with an</span>
  <span class="comment">//  |nsCOMPtr|.</span>

nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">getter_AddRefs(</span>CreateAFoo()<span class="notice">)</span> );
  <span class="comment">// |getter_AddRefs| is a synonym for |dont_AddRef| that may look better to</span>
  <span class="comment">//  you when applied to functions that return |AddRef|ed pointers</span>

nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">dont_AddRef(</span>CreateAFoo()<span class="notice">)</span> );
  <span class="comment">// or, maybe you don't like it better...</span>
</pre>
</td></tr></tbody></table>
<h5 name="nsCOMPtr.3CT.3E_.3D_.2F.2A_call_QueryInterface_but_don.27t_AddRef_.2A.2F"> <code>nsCOMPtr&lt;T&gt; = </code>/* call <code>QueryInterface</code> but don't <code>AddRef</code> */ </h5>
<p>You'll notice this quadrant of the table is marked `n/a'. There is no explicit directive that means "call <code>QueryInterface</code>, but don't <code>AddRef</code> the result". This option corresponds to the situation where you are calling a getter that returns an object of the wrong type. It has already <code>AddRef</code>ed the object, so you don't want to, but you need to get a different interface out of it. Well, you can't have it. <code>QueryInterface</code> always <code>AddRef</code>s it's result, and there is no substitute for calling <code>QueryInterface</code> to get the right type. The solution is a two step process.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// ...</span>

  <span class="comment">// The getter returns an already |AddRef|ed object (of the wrong type)...</span>
nsCOMPtr&lt;nsIBar&gt; bar( <span class="notice">getter_AddRefs(</span>CreateBar()<span class="notice">)</span> );
  <span class="comment">// ...which I must query for the right type</span>
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="notice">do_QueryInterface(</span>bar<span class="notice">)</span> );
</pre>
</td></tr></tbody></table>
<p>One unfortunate trap that people fall into in this case is forgetting that their getter function <code>AddRef</code>ed the result. Which leads them to type in code that looks like this:
</p>
<table>
<tbody><tr>
<td>
<pre class="eval">nsCOMPtr&lt;nsIFoo&gt; foo( <span class="warning">do_QueryInterface(CreateBar())</span> );
  <span class="comment">// Oops!  The interface returned by |CreateBar| leaks.</span>
  <span class="comment">//  You _must_ handle this case with the two step solution shown above.</span>

  <span class="comment">// Seems unlikely, you say?  You're more likely to see it in a form like this</span>
nsCOMPtr&lt;nsIFoo&gt; foo( <span class="warning">do_QueryInterface(aList-&gt;ElementAt(i))</span> );
  <span class="comment">// |ElementAt|, like all good getters, |AddRefs| it's result</span>
  <span class="comment">//  which would be dropped on the floor, after querying it for the needed</span>
  <span class="comment">//  interface</span>
</pre>
</td></tr></tbody></table>
<p>Bugzilla <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=8221">bug# 8221</a> is specifically about finding and fixing this particular kind of leak.
</p>
<h4 name="nsCOMPtr_helpers"> <code>nsCOMPtr</code> helpers </h4>
<h5 name="nsCOMPtr.3CT.3E_.3D_do_QueryReferent.28_nsIWeakReference.2A_.29.2CnsCOMPtr.3CT.3E_.3D_do_QueryReferent.28_nsIWeakReference.2A.2C_nsresult.2A_.29"> <code>nsCOMPtr&lt;T&gt; = do_QueryReferent( nsIWeakReference* )</code>,<br><code>nsCOMPtr&lt;T&gt; = do_QueryReferent( nsIWeakReference*, nsresult* )</code> </h5>
<p><code>do_QueryReferent</code> exists to facilitate weak references based on <a class="external" href="http://www.mozilla.org/projects/xpcom/weak_references.html"><code>nsIWeakReference</code></a>. An <code>nsIWeakReference</code> is an {{mediawiki.external('XP')}}COM object that acts as a proxy for another object. The <code>nsIWeakReference</code> and this other object have a special relationship. They know about each other, but neither holds an owning reference to the other. The two objects cooperate to ensure that neither ever holds a dangling pointer to the other. Holding an owning reference on the <code>nsIWeakReference</code> object allows you to get to this other object when you need to, but does not require it to go on living, just for you. To get to the object, you ask the <code>nsIWeakReference</code> object to <code>QueryInterface</code> it on your behalf. If the object still exists and supports the requested interface, you will (hopefully, temporarily) hold an owning reference to it.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval">nsIWeakReference* weakPtr = ...;

weakPtr-&gt;QueryReferent(
</pre>
</td></tr></tbody></table>
<h3 name="Using_an_nsCOMPtr.3CT.3E_as_a_T.2A"> Using an <code>nsCOMPtr&lt;T&gt;</code> as a <code>T*</code> </h3>
<h4 name="Using_an_nsCOMPtr_as_a_pointer"> Using an <code>nsCOMPtr</code> as a pointer </h4>
<h4 name=".60In.27_Parameters"> `In' Parameters </h4>
<h4 name=".60Out.27_Parameters:_getter_AddRefs"> `Out' Parameters: <code>getter_AddRefs</code> </h4>
<p>Assignment into an <code>nsCOMPtr</code> is fairly easy to understand. The <code>nsCOMPtr</code> <code>Release</code>s its old value, if any, and then assigns in the new value, <code>AddRef</code>ing, and/or calling <code>QueryInterface</code> as you specified with the directives described above. These rules apply equally to the `assignment' that happens when copying parameters or function results that are declared to be <code>nsCOMPtr</code>s. If we want <code>nsCOMPtr</code>s to be a viable substitute for raw {{mediawiki.external('XP')}}COM interface pointers, however, we will need to deal with the issue of `out' parameters. Many {{mediawiki.external('XP')}}COM functions return interface pointers as results through parameters, e.g.,
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Getters can return interface pointers through `out' parameters...</span>

nsresult GetFoo( nsIFoo** );     <span class="comment">// a standard getter</span>
nsresult GetFoo2( nsIFoo*&amp; );    <span class="comment">// a non-standard getter</span>
nsresult GetSomething( void** ); <span class="comment">// an `un-typed' getter</span>
  <span class="comment">// Note: |QueryInterface| is an example of a `un-typed' getter</span>
</pre>
</td></tr></tbody></table>
<p>We must be able to pass <code>nsCOMPtr</code>s by pointer or reference, into routines for use as `out' parameters. The problem is, that inside the getter there is no knowledge of <code>nsCOMPtr</code>s. It thinks it's getting a pointer (or a reference) to a raw {{mediawiki.external('XP')}}COM interface pointer. <code>nsCOMPtr</code>s smart assignment operators will not be called. The old value, if any, will be leaked.
</p><p>This is where the <code>getter_AddRefs( nsCOMPtr&amp; )</code> comes in. <code>getter_AddRefs</code> <code>Release</code>s the old value, if any, clears it out, and returns a pointer to it, allowing the getter to fill in your <code>nsCOMPtr</code> with a new <code>AddRef</code>ed value. We use <code>getter_AddRefs</code> as a sort of replacement for the <code>&amp;</code> that we would apply to a raw {{mediawiki.external('XP')}}COM interface pointer in these situations. <code>getter_AddRefs</code> packages up all the magic we normally get from <code>nsCOMPtr</code>s constructors and assignment operators.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// raw [XP]COM interface pointers...</span>

nsIFoo<span class="notice"><span class="plain">*</span></span> foo;

GetFoo(<span class="notice">&amp;</span>foo);
GetFoo2(foo);
GetSomething(<span class="notice">(void**)&amp;</span>foo);
</pre>
</td><td>
<pre class="eval"><span class="comment">// |nsCOMPtr|s...</span>

<span class="notice">nsCOMPtr&lt;</span>nsIFoo<span class="notice">&gt;</span> foo;

GetFoo(<span class="notice">getter_AddRefs(</span>foo<span class="notice">)</span>);
GetFoo2(<span class="notice"><span class="plain">*getter_AddRefs(</span></span>foo<span class="notice">)</span>);
GetSomething(<span class="notice">getter_AddRefs(</span>foo<span class="notice">)</span>);
</pre>
</td></tr></tbody></table>
<p>Why not just overload <code>operator&amp;</code> to do this work? Several reasons: it would become inconvenient take the address of an <code>nsCOMPtr</code> in all other situations; the name `<code>getter_AddRefs</code>' enforces the notion that a certain behavior is required of the getter; and once upon a time, there was another possibility (as you're about to learn).
</p><p>Is there a <code>getter_doesnt_AddRef( nsCOMPtr&amp; )</code> for getters that return non-<code>AddRef</code>ed results through a parameter? No, there isn't. Once upon a time, there was, but it went away for three reasons:
</p>
<ul><li> It is against the rules of {{mediawiki.external('XP')}}COM for a getter to return a non-<code>AddRef</code>ed interface pointer through a parameter (if you see it, report a bug).
</li><li> <code>getter_doesnt_AddRef</code> had complex ramifications that ended up making <code>nsCOMPtr</code>s either bigger or slower than raw {{mediawiki.external('XP')}}COM interface pointers.
</li><li> You can still call such a getter and put the result into an <code>nsCOMPtr</code> with a temporary, e.g.,
</li></ul>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Calling a getter that (illegally) doesn't |AddRef| its result...</span>

nsIFoo* temp;
nsresult rv = <span class="warning">GetFoo_WithoutAddRef(</span>&amp;temp<span class="warning">)</span><span class="plain">;
   </span><span class="comment">// Note to self: must report |GetFoo_WithoutAddRef| as a bug, all getters</span>
  <span class="comment">//  must |AddRef|</span>
nsCOMPtr&lt;nsIFoo&gt; foo = temp;
</pre>
</td></tr></tbody></table>
<h4 name=".60In.2FOut.27_Parameters"> `In/Out' Parameters </h4>
<p>What about `in/out' parameters?
</p>
<h3 name="Efficiency_and_Correctness"> Efficiency and Correctness </h3>
<h4 name="The_Costs_of_nsCOMPtr"> The Costs of <code>nsCOMPtr</code> </h4>
<p><code>nsCOMPtr</code> is tuned to be a viable replacement for raw {{mediawiki.external('XP')}}COM interface pointers, anywhere you would use one as an owning reference. <code>nsCOMPtr</code>s performance is generally slightly <i>more</i> efficient that raw pointers in space, and negligably less efficient in time. Performance concerns should not deter you from using <code>nsCOMPtr</code>. The patterns presented throughout this section will help you get the most out of <code>nsCOMPtr</code>.
</p>
<h5 name="Space"> Space </h5>
<p>In general, <code>nsCOMPtr</code> <i>can</i> be more efficient in space than using raw {{mediawiki.external('XP')}}COM pointers. This is primarily because it factors its destructor, and the more complicated constructors and assignment operators. By following the optimization tips in this section, you will write code that generates fewer bytes of object than you might with raw pointers. Even if you don't follow these suggestions, your <code>nsCOMPtr</code> code may still end up smaller, or at worst only negligable bulkier than the raw pointer version. See <a class="external" href="http://www.mozilla.org/projects/xpcom/nsCOMPtr/bloat.html">Code Bloat [LONG, summary at top</a>] for details, though the recommendations from that document are re-iterated here.
</p>
<h5 name="Time"> Time </h5>
<p><span class="editor-note"><span class="plain">[[More time-performance measurements are needed.]]</span></span>
</p><p>In places where two or more subroutines calls are required, i.e., of <code>AddRef</code>, <code>Release</code>, and <code>QueryInterface</code>, some <code>nsCOMPtr</code> routines are factored, and hence, require additional time corresponding to invoking a subroutine. This time is negligable, especially in the face of work done by <code>QueryInterface</code>, and the work that may be done by <code>Release</code>.
</p><p>In all other cases, <code>nsCOMPtr</code> does only the work you would have done by hand. The bulk of the work for which an <code>nsCOMPtr</code> is used is dereferencing with <code>operator-&gt;</code>, just as it is with a primitive pointer. On every platform, this operation generates the exact same code, and takes the same time, as performing this operation on a raw {{mediawiki.external('XP')}}COM interface pointer. The destructor, which corresponds to client code calling <code>Release</code> against a raw {{mediawiki.external('XP')}}COM interface pointer, is factored, requiring the extra time required to invoke a subroutine call, though this is balanced against the cost already present in both cases of calling <code>Release</code> which may, in turn, invoke <code>delete</code> and the referents destructor. All <code>nsCOMPtr</code>s constructors and assignment operators are inline. The simple constructors, i.e., those that don't query, do only exactly the same work that you would do by hand. Any routines that call more than one of <code>AddRef</code>, <code>Release</code>, or <code>QueryInterface</code>, are factored, and hence have the additional cost of invoking a subroutine call.
</p><p>Only the fact that some routines are factored, thus introducing the overhead of an additional subroutine call, and that initialization cannot be by-passed, cause any extra run-time cost for <code>nsCOMPtr</code> over raw {{mediawiki.external('XP')}}COM interface pointers. Space and time trade-offs are finely balanced in <code>nsCOMPtr</code>. The factored routines are the direct result of bloat measurements.
</p>
<h4 name="Prefer_Construction_to_Assignment"> Prefer Construction to Assignment </h4>
<p>The most efficient way, in both time and space, to get a value into an <code>nsCOMPtr</code> is at construction time. Prefer construction over assignment whenever reasonable. Initialize member <code>nsCOMPtr</code>s in the member initialization clause of your constructor.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Initialize member |nsCOMPtr|s in the member initialization clause of your</span>
<span class="comment">//  constructor...</span>

class Bar
  {
    public:
      Bar( nsIFoo* initial_fooPtr );
      <span class="comment">// ...</span>
    private:
      nsCOMPtr&lt;nsIFoo&gt; mFooPtr;
  };

Bar::Bar( nsIFoo* initial_fooPtr )
    : <span class="notice">mFooPtr(initial_fooPtr)</span> <span class="comment">// initialize it _here_</span>
  {
    <span class="comment">// not here</span>
  }
</pre>
</td></tr></tbody></table>
<p>Additionally, there is an optimization pattern using a temporary that converts assignment form to construction form.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Default construction, followed by</span>
<span class="comment">//  assignment is not as efficient...</span>

nsCOMPtr&lt;nsIFoo&gt; foo;
nsresult rv=GetFoo(getter_AddRefs(foo));





</pre>
</td><td>
<pre class="eval"><span class="comment">// ...as construction alone.</span>

<span class="notice">nsIFoo* temp;</span>
nsresult rv=GetFoo(<span class="notice">&amp;temp</span>);
nsCOMPtr&lt;nsIFoo&gt; foo<span class="notice"><span class="plain">=dont_AddRef(temp);</span></span>

  <span class="comment">// Remember this `raw-pointer, call</span>
  <span class="comment">//  getter, assign |dont_AddRef|'</span>
  <span class="comment">//  pattern.  It  crops up in many</span>
  <span class="comment">//  efficiency discussions.</span>
</pre>
</td></tr></tbody></table>
<p>In both cases you end up with <code>foo</code>, a valid <code>nsCOMPtr</code> whose value was set with the product of <code>GetFoo</code>, and <code>rv</code> the status returned by <code>GetFoo</code>. The case using the temporary, however, uses construction to put the value into the <code>nsCOMPtr</code>, which (though slightly more complicated in source) is more efficient than default construction followed by assignment, the course of events followed by the simpler example.
</p>
<h4 name="Prefer_Destruction_to_Assignment"> Prefer Destruction to Assignment </h4>
<h4 name="Prefer_do_QueryInterface_to_calling_QueryInterface"> Prefer <code>do_QueryInterface</code> to calling <code>QueryInterface</code> </h4>
<h4 name="Iterating"> Iterating </h4>
<p>There is a very common idiom for iterating over data-structures with normal pointers, e.g.,
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Iterating with pointers to non-[XP]COM objects...</span>

Node* p = ...;
while ( p )
  {
    <span class="comment">// ...</span>
    p = p-&gt;next;
  }
</pre>
</td></tr></tbody></table>
<p>One often sees this pattern expressed as a <code>for</code> loop, as well. Consider, however, what would happen if you were trying to do this with a raw {{mediawiki.external('XP')}}COM interface pointer.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Iterating with raw [XP]COM interface pointers...</span>

nsIDOMNode* p = ...;
while ( p )
  {
    <span class="comment">// ...</span>
    <span class="warning">p-&gt;GetNext(&amp;p);</span>
      <span class="comment">// Trouble!  We overwrote |p| without |Release|ing it.</span>
  }
</pre>
</td></tr></tbody></table>
<p>Oops! We just failed to <code>Release</code> <code>p</code> before putting a new pointer into it. People do this a lot, and it turns out to be a big source of leaks in normal {{mediawiki.external('XP')}}COM code. Well, could we do this instead?
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Iterating with raw [XP]COM interface pointers...</span>

nsIDOMNode* p = ...;
while ( p )
  {
    <span class="comment">// ...</span>
    <span class="warning">NS_RELEASE(p);
    p-&gt;GetNext(&amp;p);</span>
      <span class="comment">// Trouble!  We tried to call a member function of a pointer</span>
      <span class="comment">//  that may be dangling or |NULL|.</span>
  }
</pre>
</td></tr></tbody></table>
<p>Unfortunately, not. After the <code>Release</code>, <code>p</code> <i>could</i> be dangling. In fact, if you used the <code>NS_RELEASE</code> macro, <code>p</code> would be <code>NULL</code> by the time you got to the <code>GetNext</code> call.
</p><p>Now imagine that you've written the same thing with <code>nsCOMPtr</code>.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Iterating with |nsCOMPtr|s...</span>

nsCOMPtr&lt;nsIDOMNode&gt; p = ...;
while ( p )
  {
    <span class="comment">// ...</span>
    <span class="warning">p-&gt;GetNext( getter_AddRefs(p) );</span>
      <span class="comment">// Trouble!  We tried to call a member function through a |NULL| pointer.</span>
  }
</pre>
</td></tr></tbody></table>
<p>Using <code>nsCOMPtr</code> is exactly like using raw {{mediawiki.external('XP')}}COM interface pointers, here. <code>getter_AddRefs</code> <code>Release</code>s and clears out <code>p</code> before you assign into it, i.e., before <code>GetNext</code> is called. Which means that by the time we get around to calling <code>GetNext</code>, we are trying to call it through a <code>NULL</code> pointer. Unlike raw {{mediawiki.external('XP')}}COM interface pointers, <code>nsCOMPtr</code> will fire an <code>assert</code> instead of blindly trying to call <code>GetNext</code> through a <code>NULL</code> pointer.
</p><p>That's the problem. So what's the solution? If this were raw {{mediawiki.external('XP')}}COM interface pointers, we'd probably introduce a temporary. We can do the same thing with <code>nsCOMPtr</code>.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Safe iterating with raw [XP]COM</span>
<span class="comment">//  interface pointers...</span>

nsIDOMNode<span class="notice"><span class="plain">*</span></span> p = ...;
while ( p )
  {
    <span class="comment">// ...</span>

      <span class="comment">// Introduce a temporary so we</span>
      <span class="comment">//  don't stomp on |p|</span>
    nsIDOMNode<span class="notice"><span class="plain">*</span></span> temp = p;
    temp-&gt;GetNext(<span class="notice">&amp;</span>p);
    <span class="notice">NS_RELEASE(temp);</span>
  }
</pre>
</td><td>
<pre class="eval"><span class="comment">// Safe iterating with |nsCOMPtr|...</span>


<span class="notice">nsCOMPtr&lt;</span>nsIDOMNode<span class="notice">&gt;</span> p = ...;
while ( p )
  {
    <span class="comment">// ...</span>

      <span class="comment">// Introduce a temporary so we</span>
      <span class="comment">//  don't stomp on |p|</span>
    <span class="notice">nsCOMPtr&lt;</span>nsIDOMNode<span class="notice">&gt;</span> temp = p;
    temp-&gt;GetNext(<span class="notice">getter_AddRefs(</span>p<span class="notice">)</span>);
  }

</pre>
</td></tr></tbody></table>
<p>Although the <code>nsCOMPtr</code> parallel is easy to understand, it suffers from doing one extra <code>AddRef</code> and one extra <code>Release</code> compared to the raw pointer scheme. A slight transformation makes the code uglier, but (possibly negligably) more efficient.
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// Safe, efficient, iterating with |nsCOMPtr|...</span>

nsCOMPtr&lt;nsIDOMNode&gt; p = ...;
while ( p )
  {
    <span class="comment">// ...</span>
    nsIDOMNode* next;
    p-&gt;GetNext(&amp;next);
    p = dont_AddRef(next);
  }

  <span class="comment">// Look!  It's our friend, the `raw pointer, call getter, assign</span>
  <span class="comment">//  |dont_AddRef|' pattern.</span>
</pre>
</td></tr></tbody></table>
<h4 name="Writing_Getters"> Writing Getters </h4>
<h3 name="Compiler_Annoyances"> Compiler Annoyances </h3>
<h2 name="Frequently_Asked_Questions"> Frequently Asked Questions </h2>
<div class="author-note">
<p>This section will help you if you're fixing a broken build, or have what you think is a quick obvious question, and you don't have time to read the {{mediawiki.external('#reference_manual Reference Manual')}}. This FAQ usually just refers back directly to the appropriate answer, there. If you're looking here just to learn about <code>nsCOMPtr</code>s, you'll get a better introduction in the {{mediawiki.external('#users_guide Getting Started Guide')}}.
</p>
</div><div class="contents">
<ul><li> {{mediawiki.external('#FAQ_buildtime_errors Buildtime Errors')}}
</li><li> {{mediawiki.external('#FAQ_runtime_errors Runtime Errors')}}
</li><li> {{mediawiki.external('#FAQ_how_to How do I...')}}
</li><li> {{mediawiki.external('#FAQ_general General')}}
</li></ul>
</div>
<p>The FAQ is divided into sections to help you find what you're looking for faster. In most cases, the answer will just refer back into the reference manual, above. No need to explain things twice <code><span class="plain">:-)</span></code>.
</p>
<h3 name="Buildtime_Errors"> Buildtime Errors </h3>
<p>The build just broke. It's not in your code, or it's not on your platform, but there's an <code>nsCOMPtr</code> on the line where the error is and you're suspicious. You're looking in the right place.
</p>
<h4 name="comparing_an_nsCOMPtr_to_a_raw_.5BXP.5DCOM_interface_pointer"> comparing an <code>nsCOMPtr</code> to a raw [XP]COM interface pointer </h4>
<h4 name="declaring_an_nsCOMPtr_to_a_forward-declared_class"> declaring an <code>nsCOMPtr</code> to a forward-declared class </h4>
<h4 name="not_linking_to_XPCOM"> not linking to XPCOM </h4>
<h4 name="not_including_nsCOMPtr.h"> not including nsCOMPtr.h </h4>
<h4 name="different_settings_of_NSCAP_FEATURE_DEBUG_PTR_TYPES"> different settings of <code>NSCAP_FEATURE_DEBUG_PTR_TYPES</code> </h4>
<h3 name="Runtime_Errors"> Runtime Errors </h3>
<h4 name="NS_ASSERTION_.22QueryInterface_needed.22"> <code>NS_ASSERTION</code> "QueryInterface needed" </h4>
<h4 name="NS_PRECONDITION_.22You_can.27t_dereference_a_NULL_nsCOMPtr_with_operator-.3E.28.29.22"> <code>NS_PRECONDITION</code> "You can't dereference a NULL nsCOMPtr with operator-&gt;()" </h4>
<h4 name="NS_PRECONDITION_.22You_can.27t_dereference_a_NULL_nsCOMPtr_with_operator.2A.28.29.22"> <code>NS_PRECONDITION</code> "You can't dereference a NULL nsCOMPtr with operator*()" </h4>
<h3 name="How_do_I..."> How do I... </h3>
<h4 name="initialize_an_nsCOMPtr.3F"> initialize an <code>nsCOMPtr</code>? </h4>
<h4 name="Release_an_nsCOMPtr_before_it_goes_out_of_scope.3F"> <code>Release</code> an <code>nsCOMPtr</code> before it goes out of scope? </h4>
<p>Assign <code>0</code> into it. Whenever an <code>nsCOMPtr</code> takes on a new value, it always <code>Release</code>s its old value, if any. Assigning in the value <code>0</code> is just like assigning in a raw pointer that happens to be <code>NULL</code>. The old referent will be <code>Release</code>d. [See {{mediawiki.external('#ref_assignment Initialization and Assignment')}} for more details]
</p><p>You should note, though, that there is a small performance penalty for this. The <code>nsCOMPtr</code> will still exercize logic in its destructor to attempt to <code>Release</code> the value it has at that time. The optimal solution is to arrange the lifetime of your <code>nsCOMPtr</code> to correspond to exactly how long you want to hold the reference. E.g., using blocks as in this sample
</p>
<table>
<tbody><tr>
<td>
<pre class="eval"><span class="comment">// The most efficient scheme is to scope your |nsCOMPtr| to live exactly as long</span>
<span class="comment">//  as you need to hold the reference</span>

nsresult
SomeLongFunction( nsIBar* aBar )
  {
    nsresult rv;
    <span class="comment">// ...</span>

    {
      <span class="comment">// I only need the |nsIFoo| interface for a short time</span>
      <span class="comment">//  so I control its lifetime by declaring it inside</span>
      <span class="comment">//  a block statement.</span>

      nsCOMPtr&lt;nsIFoo&gt; foo( do_QueryInterface(aBar, &amp;rv) );
      if ( foo )
        foo-&gt;DoSomeFooThing();

      <span class="comment">// |foo| goes out of scope, and so |Release|s its referent, here</span>
    }

    <span class="comment">// ...tons of stuff here, during which I don't need an |nsIFoo|</span>

    return rv;
  }
</pre>
</td></tr></tbody></table>
<div class="editor-note">
<p><span class="plain"> [[Move this discussion to the </span>{{mediawiki.external('#ref_efficiency efficiency section')}}, and link to it from here.]]
</p>
</div>
<h4 name="make_an_nsCOMPtr_leak_.28for_a_debug_test.29.3F"> make an <code>nsCOMPtr</code> leak (for a debug test)? </h4>
<h4 name="call_a_getter_that_uses_a_raw_.5BXP.5DCOM_interface_pointer_as_an_.60in.2Fout.27_parameter.3F"> call a getter that uses a raw [XP]COM interface pointer as an `in/out' parameter? </h4>
<h4 name="call_a_getter_that_fills_in_an_nsIFoo.2A&amp;_parameter.3F"> call a getter that fills in an <code>nsIFoo*&amp;</code> parameter? </h4>
<h4 name="call_a_getter_that_doesn.27t_AddRef_its_result.3F"> call a getter that doesn't <code>AddRef</code> its result? </h4>
<p>Any {{mediawiki.external('XP')}}COM function that returns an interface pointer, i.e., a `getter', must have already <code>AddRef</code>ed that pointer. If it didn't, you should probably report it as a bug. No matter which code pattern you use to solve this problem, you should comment it, e.g., <code><span class="comment">// Warning: this getter doesn't AddRef() its result</span></code>. If the getter returns the new pointer as its function result, no worries,
</p>
<table>
<tbody><tr>
<td>
<p><br> 
</p>
</td></tr></tbody></table>
<h3 name="General"> General </h3>
<h4 name="Does_nsCOMPtr_bloat_the_code.3F"> Does <code>nsCOMPtr</code> bloat the code? </h4>
<h4 name="Are_nsCOMPtrs_fast.3F_Can_I_use_them_in_tight_loops.3F"> Are <code>nsCOMPtr</code>s fast? Can I use them in tight loops? </h4>
<h3 name="Bibliography"> Bibliography </h3>
<h4 name="Web_Resources"> Web Resources </h4>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsCOMPtr.h">nsCOMPtr.h</a></span>, and <span class="doc-title"><a class="external" href="http://lxr.mozilla.org/seamonkey/source/xpcom/glue/nsCOMPtr.cpp">nsCOMPtr.cpp</a></span> are the source to <code>nsCOMPtr</code>. You can examine the source to <code>nsCOMPtr</code> online using (the wonderful) <a class="external" href="http://lxr.mozilla.org/">LXR</a>. Exploring this code is not an adventure for the faint of heart.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.mozilla.org/projects/xpcom/Ownership.html">Some COM Ownership Guidelines</a></span>.
</p>
</div><div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.develop.com/dbox/cxx/InterfacePtr.htm">Interface Pointers Considered Harmful</a></span> by Don Box originally appeared in the September 1995 issue of "The C++ Report".
</p>
</div><div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.develop.com/dbox/cxx/SmartPtr.htm">COM Smart Pointers Even More Harmful</a></span> by Don Box is a follow-up article that originally appeared in the February 1996 issue of "The C++ Report".
</p>
</div>
<h4 name="Books"> Books </h4>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201634465">Essential COM</a></span> by Don Box.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201379686">Effective COM</a></span> by Don Box, et al.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201889544">The C++ Programming Language (3rd Edition)</a></span> by Bjarne Stroustrup.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201924889">Effective C++ (2nd Edition): 50 Specific Ways to Improve Your Programs and Designs</a></span> by Scott Meyers.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/020163371X">More Effective C++ : 35 New Ways to Improve Your Programs and Designs</a></span> by Scott Meyers.
</p>
</div>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201310155">Effective C++ CD: 85 Specific Ways to Improve Your Programs and Designs</a></span> by Scott Meyers.
</p>
</div>
<h4 name="People"> People </h4>
<div class="biblio-entry">
<p><span class="doc-title"><a class="external" href="http://www.develop.com/dbox/">Don Box</a></span> is a smart guy who has been writing about COM programming for a long time.
</p>
</div>
<div class="originaldocinfo">
<h2 name="Original_Document_Information"> Original Document Information </h2>
<ul><li> Author(s): <a class="external" href="mailto:scc@mozilla.org">Scott Collins</a>
</li><li> Last Updated Date: December 11, 2001
</li><li> Copyright Information:  Copyright © 1999, 2000 by the Mozilla organization; use is subject to the <a class="external" href="http://www.mozilla.org/MPL/">MPL</a>.  Portions of this content are © 1998–2007 by individual mozilla.org contributors; content available under a Creative Commons license | <a class="external" href="http://www.mozilla.org/foundation/licensing/website-content.html">Details</a>.
</li></ul>
</div>
Revert to this revision