[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