[C++-sig] Re: pure virtual methods with pyste

David Abrahams dave at boost-consulting.com
Mon Jul 28 18:45:07 CEST 2003


David Abrahams <dave at boost-consulting.com> writes:

> Nicodemus <nicodemus at globalite.com.br> writes:
>
>>
>> It works, i.e., we can use instances of derived classes in C++ and we
>> can override a() in Python, but it is not safe, because you can
>> instantiate Abstract, and calling its a method will make Python
>> crash. Adding no_init prevents the class from being instantiated, even
>> in a derived class, so that does not work. There's a way to support
>> both usages at the same time?
>
> Not without changes to Boost.Python.  We need a "default
> implementation" of a() which raises a Python exception or a version
> of call_method<> which refuses to call the method if it's actually in
> the same class... possibly also a smarter version of no_init would
> help, though I am sure it is not enough.

Ah, wait, try this:

  struct Abstract {
    virtual void a() = 0;
  };

  struct AbstractWrap: Abstract
  {
      AbstractWrap(PyObject* self_): self(self_) {}
      void a(){
          call_method<void>(self, "a");
      }

      void default_a()
      {
          PyErr_SetString(PyExc_RuntimeError, "pure virtual called");
          throw error_already_set();
      }

      PyObject* self;
  };

  void call(Abstract* a)
  {
      a->a();  }

  BOOST_PYTHON_MODULE(test)
  {
      class_<Abstract, AbstractWrap, boost::noncopyable>("Abstract")
          .def("a", &Abstract::a)
          .def("a", &AbstractWrap::default_a)
          ;

      def("call", call);
  }

I just wish I knew a way to detect that a function was pure-virtual so
we could have Boost.Python generate that default_a automatically.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list