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

David Abrahams dave at boost-consulting.com
Thu May 15 20:40:49 CEST 2003


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

> David Abrahams wrote:
>
>>So? It can be accessed from A_Wrapper, where you need to declare the
>>default implementation.
>>  
>
> Yes, but you can't tell Boost.Python about the default implementation,
> so just declaring a function "default_name" in the wrapper will have
> no effect:
>
>     const char * default_name() {
>         return A::name();
>     }
>
> ... 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().

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()

??

If so, keep in mind that Python doesn't have any notion of
"protected" interfaces.  Something's either accessible or it's not --
I suppose you can use the "private" method name hack to keep things
somewhat hidden:

    >>> class B(A):
    ...     def f(self):
    ...          self._A__name()
                

But that doesn't work too well for functions that need to be
overridden:

    >>> class B(A):
    ...     def _A__name(self):  # override "private" method
    ...          return 2
                

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?

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();
        }

>>Private virtual functions are a bigger problem; the best you can do
>>is to break the C++ rules by replicating the base class declaration
>>with the private function declared protected.
>>  
>
> I believe the problem persists: you still must tell Boost.Python about
> the default implementation.

Still not sure what you perceive the problem to be...

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





More information about the Cplusplus-sig mailing list