[C++-sig] call_back and inheritance
J. Michael Owen
mikeowen at llnl.gov
Fri Aug 2 22:36:10 CEST 2002
Whoops, looks like the tar archive I used for the example files in my post
didn't travel very well. Here's the ascii version.
Mike.
------------------------------ C++ source --------------------------------------
#include <iostream>
using namespace std;
// BPL includes.
#include "boost/python/class.hpp"
#include "boost/python/module.hpp"
#include "boost/python/call_method.hpp"
using namespace boost::python;
//------------------------------------------------------------------------------
// Class definitions.
//------------------------------------------------------------------------------
class AbstractBase {
public:
AbstractBase():
mInternalValue(-10) {}
virtual ~AbstractBase() {}
virtual void pureVirtualMethod() = 0;
virtual int processValue() = 0;
void printInternalValue() {
cout << "AbstractBase::InternalValue = " << mInternalValue << endl;
}
void callVirtualMethod() {
cout << "AbstractBase::callVirtualMethod()" << endl;
pureVirtualMethod();
}
int internalValue() {
return mInternalValue;
}
private:
int mInternalValue;
};
class Derived: public AbstractBase {
public:
Derived():
AbstractBase() {}
virtual ~Derived() {}
virtual void pureVirtualMethod() {
cout << "Derived::pureVirtualMethod()" << endl;
printInternalValue();
}
virtual int processValue() {
cout << "Derived::processValue()" << endl;
return 2*internalValue();
}
};
//------------------------------------------------------------------------------
// Call back class to provide BPL overrides for AbstractBase.
//------------------------------------------------------------------------------
class AbstractBaseCallBack: public AbstractBase {
public:
AbstractBaseCallBack(PyObject *self):
AbstractBase(),
mSelf(self) {}
void pureVirtualMethod() {
return call_method<void>(mSelf, "pureVirtualMethod");
}
int processValue() {
return call_method<int>(mSelf, "processValue");
}
private:
PyObject* mSelf;
};
//------------------------------------------------------------------------------
// Call back class to provide BPL overrides for Derived.
//------------------------------------------------------------------------------
class DerivedCallBack: public Derived {
public:
DerivedCallBack(PyObject *self):
Derived(),
mSelf(self) {}
void pureVirtualMethod() {
return call_method<void>(mSelf, "pureVirtualMethod");
}
int processValue() {
return call_method<int>(mSelf, "processValue");
}
private:
PyObject* mSelf;
};
// class DerivedCallBack: public Derived,
// public AbstractBaseCallBack {
// public:
// DerivedCallBack(PyObject *self):
// Derived(),
// AbstractBaseCallBack(self),
// mSelf(self) {}
// private:
// PyObject* mSelf;
// };
//------------------------------------------------------------------------------
// Helper methods to wrap the classes in this module.
//------------------------------------------------------------------------------
void wrapAbstractBase(module& mod) {
mod.add(class_<AbstractBase,
boost::shared_ptr<AbstractBaseCallBack>,
boost::noncopyable>("AbstractBase")
.def_init()
.def("pureVirtualMethod", &AbstractBase::pureVirtualMethod)
.def("printInternalValue", &AbstractBase::printInternalValue)
.def("callVirtualMethod", &AbstractBase::callVirtualMethod)
);
}
void wrapDerived(module& mod) {
mod.add(class_<Derived,
bases<AbstractBase>,
boost::shared_ptr<DerivedCallBack>,
boost::noncopyable>("Derived")
.def_init()
);
}
//------------------------------------------------------------------------------
// The BPL wrapped python module.
//------------------------------------------------------------------------------
BOOST_PYTHON_MODULE_INIT(callback) {
try {
module mod("callback");
// AbstractBase
wrapAbstractBase(mod);
// Derived
wrapDerived(mod);
} catch(...) {
handle_exception();
}
}
--------------------------------- python example -------------------------------
import callback
class overrideAbstract(callback.AbstractBase):
def __init__(self):
callback.AbstractBase.__init__(self)
return
def pureVirtualMethod(self):
print "This is python! overrideAbstact.pureVirtualMethod()"
return
def processValue(self):
print "This is python! overrideAbstact.processValue()"
return 10
class overrideDerived(callback.Derived):
def __init__(self):
callback.Derived.__init__(self)
return
def pureVirtualMethod(self):
print "This is python! overrideDerived.pureVirtualMethod()"
callback.Derived.pureVirtualMethod(self)
return
a = callback.Derived()
b = overrideAbstract()
c = overrideDerived()
print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
print type(a)
print a.callVirtualMethod()
print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
print type(b)
print b.callVirtualMethod()
print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
print type(c)
print c.callVirtualMethod()
print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
--
"Hey...where are the sunflower seeds?" | J. Michael Owen
o_o / | Phone: 925-423-7160
(") | Email: mikeowen at llnl.gov
\/'\/ |
____(__(,_,)_______________________________________________________________
More information about the Cplusplus-sig
mailing list