[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