[C++-sig] inheritance and virtual callbacks

Matthew Scouten matthew.scouten at gmail.com
Tue Jun 3 21:24:13 CEST 2008


So I have 2 classes, foo and bar. bar is a subclass of foo. Both bar and foo
have virtual functions intended to be overridden form python.

struct foo
{
    foo(){} ;
    foo(int init_x, int init_y){x=init_x;y=init_y;};
    int x;
    int y;

    virtual void FooCallback(){std::cout << "default foo called" <<
std::endl;};
};

struct bar : foo
{
    bar(){} ;
    bar(int init_x, int init_y, int init_z):foo(init_x,init_y){z = init_z;};

    virtual void BarCallback(){std::cout << "default bar called" <<
std::endl;};

    int z;
};

struct foo_wrapper : foo , wrapper<foo>
{
    foo_wrapper();
    foo_wrapper(const foo& f);
    foo_wrapper(int init_x, int init_y);

    virtual void FooCallback();
};

void foo_wrapper::FooCallback()
{
    std::cout << "atemptting foo callback" << std::endl;
    if (override func = this->get_override("FooCallback"))
    {
        func();
        return;
    }
    else
        std::cout << "foo callback function not found" << std::endl;
}

foo_wrapper::foo_wrapper(const foo& exch): foo(exch), wrapper<foo>(){}
foo_wrapper::foo_wrapper(): foo(), wrapper<foo>(){}
foo_wrapper::foo_wrapper(int init_x, int init_y) : foo(init_x,init_y),
wrapper<foo>(){}

struct bar_wrapper: bar, wrapper<bar>
{
    bar_wrapper();
    bar_wrapper(const bar& b);
    bar_wrapper(int init_x, int init_y, int init_z);

    virtual void BarCallback();
};

bar_wrapper::bar_wrapper(const bar& exch): bar(exch), wrapper<bar>(){}
bar_wrapper::bar_wrapper(): bar(), wrapper<bar>(){}
bar_wrapper::bar_wrapper(int init_x, int init_y, int init_z) : bar(init_x,
init_y, init_z), wrapper<bar>(){}

void bar_wrapper::BarCallback()
{
    std::cout << "atemptting bar callback" << std::endl;
    if (override func = this->get_override("BarCallback"))
    {
        func();
        return;
    }
    else
        std::cout << "bar callback function not found" << std::endl;
}

void backcaller(bar& b)
{
    b.BarCallback();
    b.FooCallback();
}

BOOST_PYTHON_MODULE(busybox)
{
    class_<foo_wrapper>("foo")
        .def(init<>())
        .def(init<int, int>())
        .ENABLE_COPY(foo)
        .def_readwrite("x", &foo::x )
        .def_readonly ("y", &foo::y )
        ;

    class_<bar_wrapper, bases<foo> >("bar")
        .def(init<>())
        .def(init<int,int,int>())
        .ENABLE_COPY(bar)
        .def_readwrite("z", &bar::z)
        ;

    def("backcaller", &backcaller);
}

in python:
>>> import busybox
>>> class myBar(busybox.bar):
...     def FooCallback(self):
...             print "this is a foo callback"
...     def BarCallback(self):
...             print "this is a bar callback"
...
>>> b = myBar()
>>> busybox.backcaller(b)
atemptting bar callback
this is a bar callback
default foo called
>>>

So the question is: why is the default FooCallback in foo getting called
rather then the FooCallback in myBar?
What can I do about it?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20080603/7928a0ec/attachment.htm>


More information about the Cplusplus-sig mailing list