[C++-sig] pointers and pyste

Nicodemus nicodemus at globalite.com.br
Sun Apr 27 21:06:33 CEST 2003


Hi Sameer,

Sameer Agarwal wrote:

> class B
> {
>     void render()
> }
> class A
> {
>     list<B*> blist;
>     void add_b(B*)
>     {
>         blist.push_back(B*)
>     }
>     
>     void render()
>     {
>         //iterate over list blist
>         // and call the render method on each object.
>     }
> }
>
> <snip>

>
> The problem starts when I call the render method in A which in turn 
> calls the render method on each of the classes stored in blist. since 
> I was using pyste to wrap the class,
> the render method  being called turned out to be the one associated 
> with the wrapped object(a subclass of B from what I can gather) and 
> not the actual class B.  


Pyste will only generate a wrapper for a class that has virtual methods, 
which is not the case of your example. I tested it and it works just 
fine (I had to change it a little to make it compile):

    #include <iostream>
    #include <list>

    struct B
    {
        void render() { std::cout << "rendering a B" << std::endl; }
    };

    struct A
    {
        std::list<B*> blist;
        void add_b(B* b)
        {
            blist.push_back(b);
        }
       
        void render()
        {
            std::list<B*>::iterator i;
            for (i = blist.begin(); i != blist.end(); ++i)
            {
                (*i)->render();
            }
        }
    };


In Python:

     >>> from test import *
     >>> b1 = B()
     >>> b2 = B()
     >>> a = A()
     >>> a.add_b(b1)
     >>> a.add_b(b2)
     >>> a.render()
    rendering a B
    rendering a B
     >>>


B::render() is called normally inside A::render(). I suppose your 
example is incomplete, and you meant that B::render to be virtual. 
Making this change, the code still works: if B::render isn't overriden 
in python, the default implementation is called, as you would expect.

> This causes problems since there was some additional funkiness with 
> the way the wrapped method was handling some references. However 
> putting an explicit exclude statement in the pyste files to exclude 
> the render method for class B solved the problem. 


What "funkiness" does it do? Because this should really not a problem at 
all: the instance of B that A receives is not *really* a B, but a 
derived class (assuming B::render is virtual), but that should give the 
same behaviour. Suppose:

struct C: B {};

If add_b receives a C instance, it will still work?

Perhaps if you post a real example we can nail down the problem? 8)

Regards,
Nicodemus.







More information about the Cplusplus-sig mailing list