wrapping virtual function returning void
Hi, Consider wrapping a class containg a virtual function returning void. The current method, which appears below for convenience, and is copied verbatim from the tutorial, seems to expect that the virtual function returns something. In other words, changing f to return void would break the code. Is this the case, or am I missing something? Please CC me on any reply. Thanks. Faheem. ********************************************************************* #include <boost/python.hpp> using namespace boost::python; struct Base { virtual ~Base() {} virtual int f() { return 0; } }; struct BaseWrap : Base, wrapper<Base> { int f() { if (override f = this->get_override("f")) return f(); // *note* return Base::f(); } int default_f() { return this->Base::f(); } }; BOOST_PYTHON_MODULE(hello) { class_<BaseWrap, boost::noncopyable>("Base") .def("f", &Base::f, &BaseWrap::default_f) ; } **********************************************************************
That's easy! struct BaseWrap : Base, wrapper<Base> { void f() { if (override f = this->get_override("f")) f(); else Base::f(); } void default_f() { Base::f(); } }; Did not hurt, did it? :) [Eric Jardim]
On Sat, 6 Aug 2005, Eric Jardim wrote:
That's easy!
struct BaseWrap : Base, wrapper<Base> { void f() { if (override f = this->get_override("f")) f(); else Base::f(); }
void default_f() { Base::f(); } };
That's interesting. So, for pure virtual functions, it would look like the version below? I don't understand what this wrapper is doing, so that makes it more difficult for me to make these deductions. According to the documentation, it overrides the base class in Python. I assume this is related to the derived class wrappers in Python knowing of their derived relationship to the base class wrapper, but I'm pretty fuzzy on the details. If some kind person wants to try to explain it, I'm all ears. Faheeem. ************************************************************************* #include <boost/python.hpp> using namespace boost::python; struct Base { virtual ~Base() {} virtual void f() = 0; }; struct BaseWrap : Base, wrapper<Base> { void f() { this->get_override("f")(); } }; BOOST_PYTHON_MODULE(hello) { boost::python::class_<BaseWrap, boost::noncopyable>("Base") .def("f", boost::python::pure_virtual(&Base::f)) ; }
2005/8/6, Faheem Mitha <faheem@email.unc.edu>:
That's interesting. So, for pure virtual functions, it would look like the version below?
Sure! I don't understand what this wrapper is doing, so that makes it more
difficult for me to make these deductions.
The wrapper<...> is doing goog things. Before the existence of wrapper<...>, when someone wanted to create derived wrapper class, they should expose a "PyObject* self" (which is a low-level pointer for the Boost.Pythonhigh-level users) as the first argument of every constructor. Now, with wrapper<...>, it is incapsulating the "PyObject* self" and you don't even have to know it exists. Besides, it creates this get_override function, that helps you if an virtual method was overriden in Python. According to the documentation, it overrides the base class in Python. I
assume this is related to the derived class wrappers in Python knowing of their derived relationship to the base class wrapper, but I'm pretty fuzzy on the details.
That's the good point of the incapsulation. While it works, you don't have to care about the details :) [Eric Jardim]
On Sun, 7 Aug 2005, Eric Jardim wrote:
The wrapper<...> is doing goog things. Before the existence of wrapper<...>, when someone wanted to create derived wrapper class, they should expose a "PyObject* self" (which is a low-level pointer for the Boost.Pythonhigh-level users) as the first argument of every constructor.
Now, with wrapper<...>, it is incapsulating the "PyObject* self" and you don't even have to know it exists. Besides, it creates this get_override function, that helps you if an virtual method was overriden in Python.
Yes, but what does it mean to say that a virtual method is overriden in Python, exactly?
According to the documentation, it overrides the base class in Python. assume this is related to the derived class wrappers in Python knowing of their derived relationship to the base class wrapper, but I'm pretty fuzzy on the details.
That's the good point of the incapsulation. While it works, you don't have to care about the details :)
Details are good. :-) Faheem.
Faheem Mitha <faheem@email.unc.edu> writes:
On Sun, 7 Aug 2005, Eric Jardim wrote:
The wrapper<...> is doing goog things. Before the existence of wrapper<...>, when someone wanted to create derived wrapper class, they should expose a "PyObject* self" (which is a low-level pointer for the Boost.Pythonhigh-level users) as the first argument of every constructor.
Now, with wrapper<...>, it is incapsulating the "PyObject* self" and you don't even have to know it exists. Besides, it creates this get_override function, that helps you if an virtual method was overriden in Python.
Yes, but what does it mean to say that a virtual method is overriden in Python, exactly?
From the Python programmer's point-of-view, he can derive classes from
Ah, good question. It means we provide the /illusion/ that it is overridden in Python. When you write class Foo_Wrapper : Foo, wrapper<Foo> { ... void f() { if (override f = get_override("f")) f(); else this->default_f(); } }; You're actually overriding f with a C++ member function that implements the illusion. It says: if the Python object corresponding to this C++ object has an attribute called "f", invoke it. Otherwise, invoke the C++ "f" member function that you would have invoked had this C++ override never been written. the wrapped class and implement an "f" method that will be called whenever, from point-of-view of the the C++ programmer who wrote Foo, someone calls the Foo::f on the wrapped object. Make sense?
That's the good point of the incapsulation. While it works, you don't have to care about the details :)
Details are good. :-) Faheem.
Trust me; you don't wanna know ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com
Faheem Mitha <faheem@email.unc.edu> writes:
On Sat, 6 Aug 2005, Eric Jardim wrote:
That's easy!
struct BaseWrap : Base, wrapper<Base> { void f() { if (override f = this->get_override("f")) f(); else Base::f(); }
void default_f() { Base::f(); } };
That's interesting. So, for pure virtual functions, it would look like the version below?
I don't understand what this wrapper is doing, so that makes it more difficult for me to make these deductions.
According to the documentation, it overrides the base class in Python.
I'm pretty sure the documentation only ever talks about overriding functions and methods, not classes. What do you really mean to say?
I assume this is related to the derived class wrappers in Python knowing of their derived relationship to the base class wrapper, but I'm pretty fuzzy on the details.
If some kind person wants to try to explain it, I'm all ears.
I'm sorry, I don't understand the question yet. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
David Abrahams -
Eric Jardim -
Faheem Mitha