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


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to