[C++-sig] Re: call_method
Brett Calcott
brett.calcott at paradise.net.nz
Sun Nov 17 03:03:46 CET 2002
> >
> > class agent
> > {
> > public:
> > virtual void do_something()
> > {
> > cout << "in c++";
> > }
> > };
> > typedef shared_ptr<agent> agent_ptr;
> > typedef vector<agent_ptr> agents;
> >
> > class engine
> > {
> > agents m_agents;
> > public:
> > void add_agent(agent_ptr const &a)
> > {
> > m_agents.push_back(a);
> > }
> >
> > void do_stuff_with_agents()
> > {
> > for_each(m_agents.begin(), m_agents.end(),
> > mem_fun(agent::do_something));
> > }
> > };
> >
> > Note that I am using shared_ptr here for my own purpose *unrelated* to
> > python implementation.
>
> Yup. You probably want a virtual destructor in agent.
Okay. That would lessen my debugging time :)
>
> > Now, what do I need to do to expose my C++ lib to python and make
> > agent::do_something overrideable in python code?
>
> Just the usual stuff. Make a py_agent class like this:
>
> struct agent_callback : agent
> {
> agent_callback(PyObject* self) : m_self(self) {}
>
> void do_something() { call_method<void>(self, "do_something"); }
>
> // expose this as "do_something"
> static void default_do_something(agent& a)
> { a.agent::do_something(); }
>
> PyObject* m_self;
> };
>
*Just* like this? A couple of posts back you said:
>> 2. Prepare a special "self_base" class that can be used as a base of
>> "callback" classes like BaseWrap from the examples. This base would
>> hold the "self" pointer.
Where is this base class in here?
> > It seems I have to touch the source code
>
> Why? How?
Cos' you need this base class to be a base of agent. Right? Or are you
multiply-inheriting? ie.
struct agent_callback : agent, boost::python::self_base { ... };
But this suggests that agent is derived directly from self_base:
> Most-importantly, when references and (smart) pointers to
> polymorphic classes are converted to python, we will attempt to
> downcast to "self_base", and if successful, we'll return the
> contained self pointer instead of a new object
>
> No, why would you? Those are shared_ptr<agent>s.
>
I know that. I thought the solution you were proposing meant I had to change
this.
> > I can't see how the solution you have can work without causing me to
> > change significantly the underlying c++ lib. Maybe I just don't get
> > it yet.
>
> HTH,
>
I'm still lost. Oh! (light bulb glimmers). Hang on. (reads shared_ptr code)
1) invoking add_agent() from python passes a shared_ptr constructed using
the custom delete functor.
2) whereas if I call add_agent() from c++, it is just the 'default'
shared_ptr, using the checked_delete<> functor.
My blind spot was not properly understanding shared_ptr. Wow, it is
*extremely* cool.
Ok, now I am getting it. The inheritance is still not clear to me.
More information about the Cplusplus-sig
mailing list