C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 34:
[34.6] Can I have a container of smart pointers to my objects?

Depends on the smart pointer. Ideally you want the answer to be Yes, because smart pointers make your life easier and make your code more robust. However if your smart pointer is std::auto_ptr, then absolutely you must not do that (and, fortunately, you will likely get a compile-time error message if you try to do that, at least with the standard library's containers).

Let's motivate this discussion with an example. This first section shows why you'd want to use smart pointers in the first place - this is what not to do:

#include <vector>

class Foo {
public:
  ...blah blah...
};

void foo(std::vector<Foo*>& v)  //  BAD FORM: a vector of dumb pointers to Foo objects
{
  v.push_back(new Foo());
  //...
  delete v.back();  // you have a leak if this line is skipped
  v.pop_back();     // you have a "dangling pointer" if control-flow doesn't reach this line
}

If control flow doesn't reach either of the last two lines, either because you don't have it in your code or you do a return or something throws an exception, you will have a leak or a "dangling pointer"; bad news. The destructor of std::vector cleans up whatever allocations were made by the std::vector object itself, but it will not clean up the allocation that you made when you allocated a Foo object, even though you put a pointer to that allocated Foo object into the std::vector object.

That's why you'd want to use a smart pointer.

Now let's talk about how to use a smart pointer. First, as was mentioned above, you cannot create a standard container of std::auto_ptr, and thankfully you will get a compile-time error message if you try:

typedef std::auto_ptr<Foo> FooPtr;  //  GOOD: using a smart-pointer

void foo(std::vector<FooPtr>& v)  //  COMPILE-TIME ERROR MESSAGE (thankfully!)
{
  //...
}

In case you care, there's a good reason this is wrong: the standard containers such as std::vector expect the contained objects to obey certain rules, and std::auto_ptr doesn't obey those rules. In particular, with std::auto_ptr objects, assignment a = b changes b: the "ownership" of the pointed-to referent gets moved from b to a. That can cause your Foo object to get deleted much earlier than you expect, such as when the std::vector grows or when you sort the vector or run any of a zillion algorithms on the vector. The main point is this: you shouldn't try to create a container of std::auto_ptr.

However you can, and normally should, use other smart pointers in your containers. There are lots of smart pointers that can be copied and still maintain shared ownership semantics, such as shared_ptr and many others. For this example, we will use shard_ptr, though you might choose another based on the semantics and performance trade-offs you desire.

typedef shared_ptr<Foo> FooPtr;  //  GOOD: using a smart-pointer

void foo(std::vector<FooPtr>& v)  //  GOOD: using a container of smart-pointer
{
  //...
}
There are lots of good articles on this general topic, such as Herb Sutter's in Dr. Dobbs and many others.