<p>经过以下答案的大量帮助和实验,我想我理解了在Cython中实现基本继承是如何工作的,我正在回答我自己的问题,以验证/改进我的理解,并希望能帮助任何将来可能遇到相关问题的人。如果这个解释有任何错误,请在下面的评论中纠正我,我会编辑它。我不认为这是唯一的方法,所以我确信其他方法也能起作用,但这是对我有效的方法。在</p>
<p><strong>概述/学到的东西:</strong></p>
<p>基本上,根据我的理解,Cython足够聪明(给出适当的信息)遍历继承层次结构/树,并根据调用它的对象类型调用虚拟函数的适当实现。在</p>
<>重要的是尝试镜像你在.pYX文件中试图包装的C++继承结构。这意味着确保:</p>
<P> 1)导入的C++/Cython cppclasses(声明为^ {CD1>})与实际C++类做</p>的方式继承
<p>2)对于每个导入的类,只声明唯一的方法/成员变量(对于在两个类中实现不同的虚拟函数,<code>BaseClass</code>和{<cd3>}不应同时具有函数声明)。只要一个从另一个继承,函数声明只需要在基类imported中。在</p>
<P> 3)Python包装类(即{{CD4>}/^ {CD5>})也应该以与实际C++类做</p>相同的方式彼此继承。
<p>4)与上述类似,虚函数的接口只需存在于<code>PyBase</code>包装类中(不应同时放入这两个类中,实际运行代码时将调用正确的实现)。在</p>
<p>5)对于每个Python包装类的子类或继承类,您需要在<code>__cinit__()</code>和<code>__dealloc__()</code>函数中同时进行<code>if type(self) is class-name:</code>检查。这将防止seg错误等。您不需要检查层次树中的“叶节点”(不会继承或子类化的类)</p>
<p>6)确保在<code>__dealloc__()</code>函数中,只删除当前指针(而不是任何继承的指针)</p>
<p>7)同样,在<code>__cinit__()</code>中,对于继承的类,请确保您设置了当前指针,以及指向您试图创建的类型的对象的所有派生指针(即<code>*self.nextDerivedptr = self.derivedptr = self.thisptr = new NextDerivedClass()*</code>)</p>
<p>希望上面的几点在您看到下面的代码时有很大的意义,它编译并运行/按照我的需要/希望它工作。在</p>
<p>基类.h:</p>
<pre><code>#ifndef __BaseClass__
#define __BaseClass__
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
class BaseClass
{
public:
BaseClass(){};
virtual ~BaseClass(){};
virtual void SetName(string name){printf("BASE: in set name\n");}
virtual float Evaluate(float time){printf("BASE: in Evaluate\n");return 0;}
virtual bool DataExists(){printf("BASE: in data exists\n");return false;}
};
#endif /* defined(__BaseClass__) */
</code></pre>
<p>DerivedClass.h:</p>
^{pr2}$
<p>NextDerivedClass.h:</p>
<pre><code> #ifndef __NextDerivedClass__
#define __NextDerivedClass__
#include "DerivedClass.h"
class NextDerivedClass:public DerivedClass
{
public:
NextDerivedClass(){};
virtual ~NextDerivedClass(){};
virtual void SetObject(BaseClass *input){printf("NEXT DERIVED CLASS: in set object\n");}
virtual bool DataExists(){printf("NEXT DERIVED CLASS: in data exists \n");return true;}
};
#endif /* defined(__NextDerivedClass__) */
</code></pre>
<p>在继承测试.pyx公司名称:</p>
<pre><code>#Necessary Compilation Options
#distutils: language = c++
#distutils: extra_compile_args = ["-std=c++11", "-g"]
#Import necessary modules
from libcpp cimport bool
from libcpp.string cimport string
from libcpp.map cimport map
from libcpp.pair cimport pair
from libcpp.vector cimport vector
cdef extern from "BaseClass.h":
cdef cppclass BaseClass:
BaseClass() except +
void SetName(string)
float Evaluate(float)
bool DataExists()
cdef extern from "DerivedClass.h":
cdef cppclass DerivedClass(BaseClass):
DerivedClass() except +
void MyFunction()
void SetObject(BaseClass *)
cdef extern from "NextDerivedClass.h":
cdef cppclass NextDerivedClass(DerivedClass):
NextDerivedClass() except +
cdef class PyBaseClass:
cdef BaseClass *thisptr
def __cinit__(self):
if type(self) is PyBaseClass:
self.thisptr = new BaseClass()
def __dealloc__(self):
if type(self) is PyBaseClass:
del self.thisptr
def SetName(self, name):
self.thisptr.SetName(name)
def Evaluate(self, time):
return self.thisptr.Evaluate(time)
def DataExists(self):
return self.thisptr.DataExists()
cdef class PyDerivedClass(PyBaseClass):
cdef DerivedClass *derivedptr
def __cinit__(self):
if type(self) is PyDerivedClass:
self.derivedptr = self.thisptr = new DerivedClass()
def __dealloc__(self):
if type(self) is PyBaseClass:
del self.derivedptr
def SetObject(self, PyBaseClass inputObject):
self.derivedptr.SetObject(<BaseClass *>inputObject.thisptr)
def MyFunction(self):
self.derivedptr.MyFunction()
cdef class PyNextDerivedClass(PyDerivedClass):
cdef NextDerivedClass *nextDerivedptr
def __cinit__(self):
self.nextDerivedptr = self.derivedptr = self.thisptr = new NextDerivedClass()
def __dealloc__(self):
del self.nextDerivedptr
</code></pre>
<p>在测试.py公司名称:</p>
<pre><code>from inheritTest import PyBaseClass as base
from inheritTest import PyDerivedClass as der
from inheritTest import PyNextDerivedClass as nextDer
a = der()
b = der()
a.SetObject(b)
c = nextDer()
a.SetObject(c)
c.DataExists()
c.SetObject(b)
c.Evaluate(0.3)
baseSig = base()
signal = der()
baseSig.SetName('test')
signal.SetName('testingone')
baseSig.Evaluate(0.3)
signal.Evaluate(0.5)
signal.SetObject(b)
baseSig.DataExists()
signal.DataExists()
</code></pre>
<p>请注意,当我打电话给:</p>
<pre><code>c = nextDer()
c.Evaluate(0.3)
</code></pre>
<p>它的工作方式是Cython沿着继承树寻找
“最新”实施评估。如果它存在于<code>NextDerivedClass.h</code>中,它会调用它(我已经尝试过了,它起作用了),但是由于它不在那里,它会更进一步并检查<code>DerivedClass</code>。该功能在那里实现,因此输出为:</p>
<pre><code>>> DERIVED CLASS: in Evaluate
</code></pre>
<p>我希望这对将来的人有所帮助,同样,如果我的理解有错误,或者只是语法/语法方面的错误,请随时在下面发表评论,我会尽力解决它们。再次感谢下面的回答者,这是他们答案的总结,只是为了帮助验证我的理解。谢谢!在</p>