[C++-sig] eposing classes with protected destructors

David Abrahams dave at boost-consulting.com
Mon Dec 23 14:14:37 CET 2002


"Daniel Paull" <dlp at fractaltechnologies.com> writes:

>> Do you have a complete template instantiation backtrace at the point
>> of the error?
>
> Here is what VC tells me for one such class:
>
> ------------------
> c:/developer/include\boost/python/detail/destroy.hpp(22) : error C2248:
> 'BooleanValue::~BooleanValue' : cannot access protected member declared
> i
> n class 'Fg::BooleanValue'
>         ..\../fg/parameters/include\fg/parameters/boolean_value.h(76) :
> see declaration of 'BooleanValue::~BooleanValue'
>         c:/developer/include\boost/python/detail/destroy.hpp(72) : see
> reference to function template instantiation 'void __cdecl
> boost::python::
> detail::value_destroyer<0,0>::execute(volatile const class
> Fg::BooleanValue *)' being compiled
> -------------------

It looks like vc6 doesn't give the backtrace.

> Interestingly, the same error occurs at a different point in this little
> example.  Here I distilled my code down to the simplest case I could
> which demonstrated the problem.  See compiler output at the end of this
> snip:
>
> -------------------
> #include <boost/python.hpp>
> using namespace boost::python;
>
> class A
> {
> public:
> 	A() {}
> protected:
> 	virtual ~A() {}
> };
>
> BOOST_PYTHON_MODULE( foo )
> {
> 	class_< A >( "A" );
> }
>
> c:/developer/tmp/boost_cvs/boost\boost/python/object/select_holder.hpp(1
> 02) : error C2248: 'A::~A' : cannot access protected member declared in
> class 'A'
>         foo.cpp(9) : see declaration of 'A::~A'
> ------------------------------------


That's not an interesting case, because in that case we expect
Boost.Python to have to destroy an A object directly.

You need:

 class A
 {
  public:
 	A() {}
  protected:
 	virtual ~A() {}
        friend class RefCountedObject<A>; // <==
 };

        ...

 	class_< A, RefCountedObject<A> >( "A" );

for this demonstration to mean anything.  I assume you were making
RefCountedObject<A> a friend in your original example.

> Furthermore, if I declare the class as:
>
> 	class_< A, boost::noncopyable >( "A" );
>
> The error is reported at python/object/value_holder.hpp, line 106.
>
> Hope all that's useful...

Nope.  Unfortunately it's all irrelevant.

>> Hmm.  rvalue_from_python_data<WrappedClass> is used when you wrap a
>> function taking a WrappedClass or WrappedClass const& argument (and a
>> few other places, like extract<WrappedClass>).  The assumption is that
>> the converter might need to create a new WrappedClass object, e.g. via
>> some implicit conversion.  I assume that's what's happening here and I
>> would be very, very surprised if you were able to compile the same
>> code with Boost 1.29.0.
>
> You would be right, there are functions that take a WrappedClass&.  

I didn't say WrappedClass&; that case doesn't cause
rvalue_from_python_data<WrappedClass> to be used.

It's only relevant for WrappedClass const& and WrappedClass arguments.

> In this case, the assumption that a new WrappedClass object may be
> created is false... at least for my current use case.

Yes, I understand that.

> Get ready to be surprised - this all worked great with a CVS version
> from a month or two back.  I think I last updated in the second half of
> November.  I can't vouch for 1.29.0 though.

Show me a small example, please. I still can't believe it.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution





More information about the Cplusplus-sig mailing list