[C++-sig] how to call base class method?
Jim Bosch
talljimbo at gmail.com
Sat May 7 04:24:41 CEST 2011
On 05/06/2011 06:51 PM, zeb wrote:
> I have 2 class exposed to python:
> class A {
> public:
> virtual int get() { return 1; }
> };
>
> class B : public A {
> public:
> virtual int get() { return 2; }
> };
>
> In python:
> obj = B()
> obj.get() # this will call B's get()
>
> For some reason, I want to call A's get() in python, like obj->A::get() in
> C++. So I have tried:
> @ Directly call base class's method in python: A.get(obj) # failed.
> @ make a wrap function to cast B to A:
> A* cast(B* obj) {
> return (A*)obj;
> }
> And try to use different call policy, like manage_new_object,
> reference_existing_object, return_internal_reference, but all failed.
> After casting, the two object actually the same object.
>>>> objB = B()
>>>> objA = cast(objB)
>>>> objA == objB
> True
>
The fact that you never get back an "A" Python object is very much a
feature rather than a bug, and while you might be able to find a way
around it, it's not recommended.
If this wasn't a virtual member function, you could have used the usual
Python syntax for a base class method call:
obj = B()
A.get(obj) # should return 1, if "get" isn't virtual
For a virtual member function, I don't think there's a way to do this
without wrapping the base class method separately, and even that
requires some extra work. I think something like this may do what you want:
int A_get(A & self) {
return self.A::get();
}
class_<A>("A")
.def("A_get", &A_get)
.def("get", &A::get)
;
You could also wrap "A_get" directly as "get" in class A, which should
allow you to use the "A.get(obj)" successfully, I think, but you might
want to make sure that it doesn't also destroy the usual (virtual)
behavior of the method in Python.
Jim
More information about the Cplusplus-sig
mailing list