Derive from C++ base class in SWIGged Python
<p>Note: The corresponding gist is <a href="https://gist.github.com/nschloe/3d8bc8a22a1bea81237c0db2c4af7a1f" rel="nofollow">here</a>.</p>

<hr>

<p>I have an abstract base class and a method that accepts a pointer to the base class, e.g.,</p>



<pre><code>#ifndef MYTEST_HPP
#define MYTEST_HPP

#include &lt;iostream&gt;
#include &lt;memory&gt;

class MyBaseClass {
  public:
    virtual
    double
    eval(const double x) const = 0;
};

class Square: public MyBaseClass {
  public:
    virtual
    double
    eval(const double x) const
    {
      return x*x;
    }
};


void
mytest(const std::shared_ptr&lt;MyBaseClass&gt; &amp; a) {
  std::cout &lt;&lt; a-&gt;eval(1.0) &lt;&lt; std::endl;
  std::cout &lt;&lt; a-&gt;eval(2.0) &lt;&lt; std::endl;
  std::cout &lt;&lt; a-&gt;eval(3.0) &lt;&lt; std::endl;
}

#endif // MYTEST_HPP
</code></pre>

<p>After SWIGging this with</p>



<pre><code>%module mytest

%{
#define SWIG_FILE_WITH_INIT
#include "mytest.hpp"
%}

%include &lt;std_shared_ptr.i&gt;
%shared_ptr(MyBaseClass);
%shared_ptr(Square);

%include "mytest.hpp"
</code></pre>

<p>I can create <code>Square</code> instances and feed them into <code>mytest</code> from within Python, e.g.,</p>

<pre><code>import mytest
a = mytest.Square()
mytest.mytest(a)
</code></pre>

<p>As expected, this will print</p>

<pre><code>1.0
4.0
9.0
</code></pre>

<p>I'd now like to derive more classes from <code>MyBaseClass</code>, but from Python. Unfortunately, simply doing</p>



<pre><code>class Cube(mytest.MyBaseClass):
    def __init__(self):
        return

    def eval(self, x):
        return x*x*x

c = Cube()
mytest.mytest(c)
</code></pre>

<p>results in the error</p>

<pre><code>Traceback (most recent call last):
  File "../source/test.py", line 14, in &lt;module&gt;
    mytest.mytest(c)
TypeError: in method 'mytest', argument 1 of type 'std::shared_ptr&lt; MyBaseClass &gt; const &amp;'
</code></pre>

<p>Any hints?</p>

<p>Got it (via <a href="http://stackoverflow.com/a/9042139/353337">http://stackoverflow.com/a/9042139/353337</a>):</p>

<p>Add the director feature to <code>MyBaseClass</code></p>

<pre><code>%module(directors="1") mytest

%{
#define SWIG_FILE_WITH_INIT
#include "mytest.hpp"
%}

%include &lt;std_shared_ptr.i&gt;
%shared_ptr(MyBaseClass);
%shared_ptr(Square);

%feature("director") MyBaseClass;

%include "mytest.hpp"
</code></pre>

<p>and properly initialize the class in Python</p>



<pre><code>class Cube(mytest.MyBaseClass):
    def __init__(self):
        mytest.MyBaseClass.__init__(self)
        return

    def eval(self, x):
        return x*x*x
</code></pre>

python c++ swig