I have a problem with Cython usage of default constructors.
My C++ class Node is the following
Node.h
class Node
{
public:
Node()
{
std::cerr << "calling no arg constructor" << std::endl;
w=0.0;
d=0.0;
}
Node(double val, double val2);
{
std::cerr << "calling 2 args constructor" << std::endl;
this->w=val;
this->d=val2;
}
private:
double d,w;
}
is wrapped in Cython as follows
cdef extern from "Node.h":
cdef cppclass Node:
Node() except +
Node(double val1, double val2) except +
double d
double w
cdef class pyNode:
cdef Node *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self):
self.thisptr = new Node()
def __cinit__(self, double val1, double val2):
self.thisptr = new Node(val1,val2)
def __dealloc__(self):
del self.thisptr
def __repr__(self):
return "d=%s w=%s" % (self.thisptr.w, self.thisptr.w )
The Cython code compiles well, but in particular when called from Python
from pyNode import pyNode as Node
n=Node(1.0,2.0)
I get the expected calling 2 args constructor string, but if I’m trying to declare a Node object from python using the “no-arguments” constructor (which should be correctly declared as __cinit__(self) I’m getting no output, this means that the no-argument constructor is not called!
How can I explicitly call it from the cinit method of the wrapped class?
The issue here is that you can’t overload
__cinit__()like that (as onlycdeffunctions can be overloaded) – instead, have it take default values, then call the right thing as needed.Edit: Essentially, you need to implement the function in a way closer to how you would in normal Python code, instead of using overloading:
Naturally, this presumes
-1is a value that isn’t useful for the function, you could use another value, or if you need every value of a double to be valid, then you might need to remove the typing, taking a Python object so that you can useNoneas the default: