For shared_ptr it matters whether the type is terminated when you pass a pointer to shared_ptr (which should usually be because you just created A ). At this point, shared_ptr will create some kind of debiter that needs the full type, and save it so that it is available when the reference count drops to zero (even if it happens in a file where A is incomplete).
For unique_ptr it is important whether this type is completed when default_delete called, which will usually be in the unique_ptr destructor (but it can also be in its reset() member or assignment operation).
Using auto_ptr with incomplete types is just undefined.
To answer the question in the header: the standard requires that shared_ptr and unique_ptr refuse to compile code that tries to remove an incomplete type. This does not guarantee 100% security, because when executing unique_ptr<base>(new derived) , the behavior may be undefined if base does not have a virtual destructor.
I believe that the execution of the code to compile the code is that GCC creates the templates at the end of the file, and the inline B destructor is not needed until B is defined, and then point A completed. If you put the definition of A and B::B into a separate file from the variable B , you will find that unique_ptr will not correctly delete A when B is destroyed (in fact, this does not even compile, since destroying B calls default_delete , and the standard states that a full type is required or the program is poorly formed).
A portable solution is to ensure the completion of A , where you define a destructor for B , so do not specify a built-in destructor if A not filled in all files.
source share