A shared_ptr
can be declared with an incomplete type, yes. The type does not need to be complete until you initialize or reset it.
When you initialize or reset a shared_ptr
to point to a new object, it creates a "deleter" that can be used to destroy the object. For example, consider the following:
// somewhere where A is incomplete:
std::shared_ptr<class A> p;
// define A
class A { /* ... */ };
p.reset(new A());
When you call reset
, A
is complete because you're creating an instance of it using new
. The reset
function creates and stores internally a deleter that will be used to destroy the object using delete
. Because A
is complete here, that delete
will do the right thing.
By doing this, shared_ptr
does not require that A
be complete when the shared_ptr<A>
is declared; it only requires that A
is complete when the shared_ptr
constructor that takes a raw pointer is invoked or when you call reset
with a raw pointer.
Note that if A
is not complete when you do one of those two things, shared_ptr
won't do the right thing and the behavior is undefined (this is explained in the documentation for boost::shared_ptr
, which is probably the best resource for learning how to use shared_ptr
correctly, regardless which version of shared_ptr
you are using (Boost, TR1, C++0x, etc.)).
However, as long as you always follow the best usage practices for shared_ptr
--notably, if you always initialize and reset a shared_ptr
directly with a pointer resulting from a call to new
--you won't have to worry about violating this rule.
This functionality isn't free: shared_ptr
has to create and store a pointer to the deleter functor; typically this is done by storing the deleter as part of the block that stores the strong and weak reference counts or by having a pointer as part of that block that points to the deleter (since you can provide your own deleter).
auto_ptr
(and unique_ptr
too) is designed to be free of any overhead: operations on it are supposed to be just as efficient as using a dumb pointer. Thus, auto_ptr
doesn't have this functionality.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…