1

How do I access derived class in python from abstract class(interface class) without exposing derived class, by only exposing abstract class. I do not want to expose derived class for python. Is there any way that I can access derived class through abstract class? The example code is:

Base.h

class Base
{
    public:
    virtual void Set(const std::vector<std::string>& AllParameters) = 0;
};

struct BaseWrap : Base, wrapper<Base>
{
    void Set(const std::vector<std::string>& AllParameters)
    {
        this->get_override("Set")(AllParameters);
    }
}

Base.cpp

BOOST_PYTHON_MODULE(Example)
{
    class_<Basewrapper , boost::noncopyable> ("Base")
        .def("Set",pure_virtual(&Base::Set))
            ;
}

Derived.h

class Derived : public Base
{
    public:
       void Set(const std::vector<std::string>& AllParameters);
       int test(int a, int b);
};        

Derived.cpp

   void Derived::Set(const std::vector<std::string>& AllParameters)
    {
      //some code here

    }

   void Derived:: test(int a , int b)
   { 
    return a+b; 
}
3
  • is there any way that we can access this derived class from python by using abstract class(not by expsoing derived classes). Commented Nov 26, 2013 at 15:33
  • Can you please provide an example of how you are trying or wanting to use it? It is not clear to me how Derived or Derived::test() is intended to be used. Commented Nov 26, 2013 at 15:54
  • i want to access this set fucntion of derived class from python through abstract base class Commented Nov 26, 2013 at 16:03

1 Answer 1

4

As far as I know, there is no way to access a class without exposing the class. Boost.Python requires the static types to be exposed. However, it is possible to obtain virtual function resolution to instance whose dynamic type has not been exposed through Boost.Python, as long as the static type has been exposed. For example, if:

  • Base and Base::foo() exposed to Boost.Python
  • Derived inherits from Base
  • Derived overrides Base::foo()

Then a handle to an instance of Derived can be passed through Boost.Python with a static type of Base* or Base&, and invoking foo() on the resulting Python object will resolve to Derived::foo().

Here is a complete code example:

#include <boost/python.hpp>

struct Base
{
  virtual int foo() = 0;
  virtual ~Base() {}
};

struct Derived
  : public Base
{
  int foo()
  {
    return 42;
  }
};

/// @brief Factory method to create Derived objects, but return as
///        Base*.  If the instance was returned as a Derived*, then
///        Derived would need to be directly exposed to Boost.Python.
Base* make_derived()
{
  return new Derived;
}

namespace python = boost::python;

/// @brief Wrapper that will provide a non-abstract type for Base.
struct BaseWrap
  : public Base, public python::wrapper<Base>
{
  int foo()
  { 
    return this->get_override("foo")();
  }
};

BOOST_PYTHON_MODULE(example)
{
  // Exposes BaseWrap in Python as Base.  This also causes C++ Base to be
  // indirectly exposed for conversions via Boost.Python's wrapper.
  python::class_<BaseWrap, boost::noncopyable>("Base")
    .def("foo", python::pure_virtual(&Base::foo))
    ;

  // Make an instance of Derived, but return the instance as Base*.  As
  // Base is indirectly exposed via the wrapper, a handle to the object
  // is passed through the Boost.Python layer.
  python::def("make_derived", &make_derived,
              python::return_value_policy<python::manage_new_object>());
}

Interactive usage:

>>> import example
>>> d = example.make_derived()
>>> d.foo()
42
>>> class Spam(example.Base):
...     def foo(self):
...         return 101
... 
>>> s = Spam()
>>> s.foo()
101
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.