[C++-sig] call_back and inheritance

Mike Owen mikeowen at speakeasy.net
Sat Aug 3 08:46:07 CEST 2002


Ah, I see what you're saying, and indeed when I remove the .def() from the 
AbstractBase definitions I can correctly override and use the AbstractBase 
from python.   Cool!

However, I still don't see how I can get the ability to override the method 
again in python classes that inherit from the Derived C++ class.   I seem to 
be having trouble trying to define a call_back class for the Derived class in 
this example, and therefore I have not been able to get a python method to 
override it's methods.  How should we handle the wrapping of Derived so we 
can override it's methods too?

Thanks for the pointers!

Mike.

Here's the modified version of the previous example where I've removed the 
.def for the pure virtual method from AbstractBase call_back again.
#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) {}
// };

//------------------------------------------------------------------------------
// 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("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()
            .def("pureVirtualMethod", &AbstractBase::pureVirtualMethod)
            );
}

//------------------------------------------------------------------------------
// The BPL wrapped python module.
//------------------------------------------------------------------------------
BOOST_PYTHON_MODULE_INIT(callback) {
  module mod("callback");

  // AbstractBase
  wrapAbstractBase(mod);
    
  // Derived
  wrapDerived(mod);

}

-- 
 "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