c++-sig@python.org
[Top] [All Lists]

[C++-sig] How to wrap many virtual function

Subject: [C++-sig] How to wrap many virtual function
From: Dennis Brakhane
Date: Fri, 16 Sep 2005 01:23:10 +0200
Hello list!

I want to wrap an interface that uses many virtual functions, some of 
them pure virtual, with many derived classes. Consider the following 
example:


struct Foo
{
     Foo(int a, int b=42);

     virtual ~Foo();

     virtual void v() = 0;
     virtual void v2();

     void showab();
     int a,b;

};

void Foo::v2()
{cout<<"foo v2"<<endl;}

struct Bar : public Foo
{
     Bar(int a,int b=42) : Foo(a,b) {}
     virtual void v();

};


void Bar::v()
{
     cout << "v" << endl;
}

void call_v(Foo& foo)
{
     foo.v();
}

void call_v2(Foo& foo)
{
     foo.v2();
}

struct FooWrap : public Foo, wrapper<Foo>
{
     void v() {this->get_override("v")();}
     void v2() {
        if (override f = this->get_override("v2"))
            f();
        else
            Foo::v2();
     }
     void default_v2()
        {
            this->Foo::v2();
        }

     FooWrap(int a, int b=42)
        : Foo(a,b)
        {}

};

struct BarWrap : public Bar, wrapper<Bar>
{
     void v()
     {
         if (override f = this->get_override("v"))
             f();
        else
            Bar::v();
     }

     void v2() {
        if (override f = this->get_override("v2"))
            f();
        else
            Foo::v2();
     }
     void default_v2()
        {
            this->Foo::v2();
        }


     BarWrap(int a, int b=42)
        : Bar(a,b)
        {}
};

Foo::~Foo()
{}

Foo::Foo(int a_, int b_)
     : a(a_),b(b_)
{}

void Foo::showab()
{
     cout << a << " " << b << endl;
}

BOOST_PYTHON_MODULE(foo)
{
     class_<FooWrap, boost::noncopyable>("Foo",init<int,optional<int> >())
        .def("v",pure_virtual(&Foo::v))
        .def("v2",&Foo::v2, &FooWrap::default_v2)
        .def("showab",&Foo::showab);

     class_<BarWrap, bases<Foo>, boost::noncopyable 
 >("Bar",init<int,optional<int> >())
        .def("v",&Bar::v)
        .def("v2",&Foo::v2, &FooWrap::default_v2); // ***

     def("call_v",call_v);
     def("call_v2",call_v2);
}



As you see, the only way to handle this I've found is to "re-wrap" each 
virtual function in any derived class. This is rather cumbersome and 
error-prone; for example, if I forget the line marked ***, the code will 
still compile cleanly, but when call_v2 is called with a Bar-derived 
class Baz defined in Python, it will call Bar's v2 instead of Baz'.

My question therefore: is there an easier way? Ie. not having to 
redeclare and wrap every virtual function?
_______________________________________________
C++-sig mailing list
C++-sig@xxxxxxxxxx
http://mail.python.org/mailman/listinfo/c++-sig

<Prev in Thread] Current Thread [Next in Thread>
  • [C++-sig] How to wrap many virtual function, Dennis Brakhane <=