[C++-sig] extending a c++ object by overriding it's virtual functions..
David Abrahams
dave at boost-consulting.com
Wed Jun 28 14:40:59 CEST 2006
Kleistereimer <kleistereimer at gmx.de> writes:
> hi dave,
>
> thankyou for your explanations and sourcecode.
>
> i have some more questions about it thought.
>
>
>
> first here is the sourcecode again:
>
>
> //Python
>>>> class Derived(Base):
> ... def f(self):
> ... return 42
>>>> base = Base()
>>>> derived = Derived()
>>>> base.f()
> 0
>>>> derived.f()
> 42
>
> //C++ code from your answer
>>1: // substitute the module name where "derived" is defined for "__main__"
>>2: python::object module = python::import("__main__");
>>3: python::object derived = module.attr("derived");
>>4: python::object b = derived( /* arguments to __init__ here */ );
>>5: int result = b.f();
Whoops:
int result = b.attrib("f")();
> 1)
> the mentioned include file <boost/python/import.hpp> is not in boost
> 1.33.1. where can i get it? is it in cvs?
Yes. Get the RC_1_34_0 branch.
> does it suffice if i get this
> .hpp file only, or do i need the complete cvs version?
I can't guarantee it works without the complete CVS
> for now i used the c api.. instead of this line.
>
> 2)
> what does the above code exactly? i think it instantiates a python
> 'Derived' class to object 'derived',
No, creates a reference to the Python class object called "derived."
> so line 3 has to be:
> 3 python::object derived = module.attr("Derived"); //capital 'D'
Your post mixes case ["so i need to hardcode the name of the
instantiated class ('derived')"] so I used lowercase, but if you
define it as Derived, obviously, capitalize.
> and at line 5 'f' is called on this instance. this gives me a compiler
> error:
> "f is no element of ..::api::object". how to solve this?
> i guess it involves something like:
> python::call_method<int>(b.ptr(),"f")
> but this fails in arg_to_python.hpp:181
> "cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();"
> how to do it corectly?
int result = b.attrib("f")();
> 3)
> so this scheme is not 'overwriting c++ virtual functions with python
I assume you mean "overriding"
> code' directly, instead it's 'deriving a python class from a c++ class,
> overwriting virtual functions,
One can only override member functions by deriving in C++, so I don't
see where your expectations for a more "direct" overriding could come
from.
> and then making an instance of this python class and access it from
> c++' right?
That's what you seemed to be wanting to do.
> this means if i have some heavily used c++ class which needs only some
> minor functions tweakable from python, i should better do it like so:
>
>
> class py_MyClass:
> def Log(self):
> ...
>
> class MyClass
> {
> MyClass() {m_PyObject = Instantiate("py_MyClass");} //using line 3 and 4
> ~MyClass() {delete m_PyObject;}
> ...
> ...
> void Log(std::string) {python::call_method<void>(m_PyObject, "Log"); }
> };
>
> because this calls into python only if one of the 'pythonized' functions
> is needed (which is seldom) but not if other c++ functions are used
> (which is extremely often)
>
>
> did i understood it right?
Not really. If you want to use derived polymorphically from C++, you
can also do this:
python::object d = derived( /*args*/ );
Base& b = python::extract<Base&>( d );
b.f();
Now only the functions you've made overridable in Python (e.g. f) will
use any part of the Python API at all, and those that aren't actually
overridden will only do a fast lookup, find nothing, and continue with
C++ code, without interpreting any bytecode.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list