Re: about boost::scoped_ptr
James Kanze wrote:
On Mar 5, 3:59 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
Barry wrote:
boost::scope_ptr is not suitable for Pimpl idom,
as the template parameter (A_impl) should be complete at the point
where you instantiate boost::scope_ptr (when you declare impl_).
I don't understand why that requirement makes it unsuitable
for the Pimpl idiom. Just because the type is incomplete at
the *declaration* of the scoped_ptr member variable, that
doesn't mean that the type in question is incomplete when this
variable is *constructed* (which happens in the constructor of
the A class in this example). As long as the type is fully
declared when the constructor of A is implemented, there
should be no problem in constructing the scoped_ptr variable
correctly.
That's not what the documentation of scoped_ptr says---I think
you're thinking of shared_ptr.
No, shared_ptr explicitly supports incomplete types. My point was that
even if scoped_ptr didn't, I can't think of any reason why it could
nevertheless be used with incomplete types as a class member function as
long as you implement the constructor and destructor for that class.
Simply declaring that class A has a member variable named
boost::scoped_ptr<IncompleteType> ptr; is not the same thing as
constructing that member variable. The construction of that variable
happens in the constructor of A, and as long as the type is not
incomplete in that context, I can't think of any reason why it wouldn't
work. Likewise for the destructor.
Instead of just saying "it might not work", could you please give me a
*precise reason* for it not to work? I want to know.
Even if boost::scoped_ptr didn't support incomplete types (I
don't remember if it does), there's no problem as long as you
implement a destructor for the A class in a context where the
type is fully declared. The destructor of the scoped_ptr
variable gets called from this destructor of A, and if the
type is complete in the context, everything should work just
fine.
It depends on the class requirements. Declaring a member
variable with the type will instantiate the class, and
std::auto_ptr requires the type to be complete in order to
instantiate the class; there's nothing you can do with it with
an incomplete type.
Exactly what is it that stops it from working? As long as the type is
complete when the constructor of the class is implemented, I can't think
of any reason why it wouldn't work.
In other words, why wouldn't this work?
// A.hh
class ToBeManaged;
class A
{
std::auto_ptr<ToBeManaged> ptr;
public:
A();
~A();
};
// A.cc
#include "A.hh"
#include "ToBeManaged.hh"
A::A() {} // Implicitly calls the constructor of 'ptr'
A::~A() {} // Implicitly calls the destructor of 'ptr'
'ptr' gets constructed here, and in this context ToBeManaged has been
fully declared. Why wouldn't it work?
Likewise for the destructor.
Boosts smart pointers generally allow
instantiating the class with an incomplete type
Are you sure those smart pointers can be constructed when the type is
incomplete? Doesn't, for example, boost::shared_ptr require for the type
to be complete when it's constructed?
In other words, can you, at least in theory, do this:
class ToBeManaged;
void foo(ToBeManaged* instance)
{
boost::shared_ptr<ToBeManaged> ptr = instance; // Will this compile?
boost::shared_ptr<ToBeManaged> ptr2; // Or even this?
...
}
, but require the
type to be complete any time a member function (e.g. the
destructor) is instantiated.
Isn't it, thus, enough for the destructor of the class (which has a
smart pointer as member variable) to have an explicitly implemented
destructor (which is implemented in a context where the type being
managed is complete)?