[C++-sig] How to wrap many virtual function
Dennis Brakhane
Dennis.Brakhane at urz.uni-heidelberg.de
Fri Sep 16 01:23:10 CEST 2005
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?
More information about the Cplusplus-sig
mailing list