[C++-sig] Re: pyste: current cvs/1_30_00 difference in treatment of overloaded members

David Abrahams dave at boost-consulting.com
Fri May 16 01:02:49 CEST 2003


Nicodemus <nicodemus at globalite.com.br> writes:

> David Abrahams wrote:
>
>>Nicodemus <nicodemus at globalite.com.br> writes:
>>  
>>>... unless we also expose it in the class_ declaration:
>>>
>>>    .def("name", &A::name, &A_Wrapper::default_name)
>>>    
>>
>>Of course you do have to do that.
>>
>>  
>>>Which, besides making the function public, can't be done because
>>>A::name is protected. Or am I missing something?
>>>    
>>
>>You're certainly missing that A_Wrapper is derived from A and so can
>>access A's protected members, including name().
>>
>
> That's what I meant by "making the function public" (sorry, I should
> have said "exported"):
>
>     class_< A, A_Wrapper >("A", init<  >())
>         .def(init< const A & >())
>         .def("get_name", &A::get_name)
>         .def("name", &A::name, &A_Wrapper::default_name)
>     ;
>
> This gives an error (obviously):
>
> test.cpp(43): error #308: function "A::name" is inaccessible
>           .def("name", &A::name, &A_Wrapper::default_name)


Oh, sorry.  You can of course stick a function in A_Wrapper which gets
you &A::name:

        static char const* (A::*a_name())() { return &A::name; }

>>Anyway, let me get this straight.  In what context don't you want to
>>make "the function" (which function?) public?
>>
>>Are you trying to prevent:
>>
>>    >>> x = A()
>>    >>> x.name()
>>
>>??
>>  
>
> Yes. I think it would be nice to mimic the C++ classes on the Python
> side as much as possible, but I know that Python has different
> semantics. My first thoughts were that one couldn't access the
> protected function from outside the class, but could override it
> inside a derived class. But on second thought, that is not a very good
> option either, because then you can't call the parent's implementation
> from the derived class that way:
>
>      class B(A):
>          def name(self):
>              return A.name(self) + 'B'  # wouldn't work, unless "name"
>              were also exported

Right.  Of course, designs which make you do that are evil anyway,
but we still have to wrap them ;-).

>>But anyway, back to your original problem.  I think you are saying you
>>want instances of A created from Python not to have a Python "name"
>>method, yet that Python classes derived from A can override A::name,
>>and that from C++, python instances of A implement "name" using the
>>C++ A::name by default.  Right?
>>
>
> Yes.
>
>>I think trying to get Python A instances not to have a name method is
>>sort of unpythonic, but be that as it may...
>>  To get overridability, you need to implement A_Wrapper::name() so
>> that
>>it dispatches into Python.  If you don't want to expose a "name"
>>attribute, you'd better implement A_Wrapper::name() something like
>>this:
>>
>>        char const* name()
>>        {
>>            if (PyObject_HasAttrString(this->self, "name"))
>>                return boost::python::call_method<char const*>(self, "name");
>>            else
>>                return A::name();
>>        }
>>  
>
> That's what I thought...

But it seems like that's not the solution you're looking for.
Unfortunately Python doesn't let you say "who's asking?" before giving
out an attribute value, so you can't hide A.name from everything
that's not a derived class of A.

> I wanted to know how to expose the default implementation of
> protected virtual methods, and also how should Pyste handle them. I
> saw two options: export them normaly, just like a public method; or
> override the function and inside it check if the python object has
> reimplemented it, otherwise call the default implementation. I
> wanted to discuss here in the list what would be the best method,
> that's all.

OK, I understand now.  I hope I helped a little at least.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list