多个 Inheritance/Virtual 函数
Multiple Inheritance/Virtual Functions
使用 Cython(充当接口,因此我可以通过 Python 调用基于 C++ 的函数),我试图包装一个复杂的 C++ classes 层次结构,所有这些最终都继承来自一个基地 class。这个奇异的基础 class 有许多虚函数,其实现根据所考虑的派生 class 而不同。派生的 classes 也有自己独特的功能。
我在通过 Cython 包装它时遇到了很多麻烦,主要是因为我找不到在每个继承的classes 属于该特定类型(而不是单数基数 class 的类型)。我也尝试过类型转换,以及尝试删除指针然后重新初始化它,但它仍然认为它指向相同的基class。示例代码如下:
inheritTest.pyx:
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()
float Evaluate(float)
bool DataExists()
SetObject(BaseClass *)
cdef class PyBaseClass:
cdef BaseClass *thisptr
def __cinit__(self):
self.thisptr = new BaseClass()
def __dealloc__(self):
del self.thisptr
cdef class PyDerivedClass(PyBaseClass):
#This is one of the solutions that I have tried
def __cinit__(self):
if(self.thisptr):
del self.thisptr
self.thisptr = new DerivedClass()
def __dealloc__(self):
del self.thisptr
def Evaluate(self, time):
#I need to call the Derived implementation of this function, not Base
return self.thisptr.Evaluate(self,time)
def SetObject(self, PyBaseClass inputObject):
#The issue here is that it looks for SetObject to be declared in BaseClass and spits an error otherwise. If I put a empty declaration, the complain is of ambiguous method overload
self.thisptr.SetObject(inputObject.thisptr)
此外,当我在我的 Python 脚本中调用 SetObject 时,我希望能够传入一个 PyDerived 对象作为输入,因为它继承自 PyBase,难道它不应该工作吗?我试过了,错误是:
参数类型不正确:需要 PyBase,得到 PyDerived
希望我的问题有意义,如果您需要任何其他信息,请告诉我:)
而不是删除 self.thisptr
的旧副本,只是让基 class 的构造函数仅在 self
的类型是基 class 时才初始化指针].
def __cinit__(self):
if type(self) is PyBaseClass:
self.thisptr = new BaseClass()
确保在基础 class __dealloc__
方法中也以相同的方式防止释放。
然后,为了避免一堆不必要的转换,在 subclass 包装器中,制作两个不同的属性,一个存储指向转换为基类型的 c++ 对象的指针 class另一个存储指向具有原始类型的 c++ 对象的指针。像这样:
cdef DerivedClass* derivedptr
def __cinit__(self):
self.derivedptr = self.thisptr = new DerivedClass()
然后,当您需要访问派生的方法时class,请改用派生指针。
确保在释放时只删除派生指针。
我从 Cython Users mailing list 上的讨论中得到了这个想法。
使用 Cython(充当接口,因此我可以通过 Python 调用基于 C++ 的函数),我试图包装一个复杂的 C++ classes 层次结构,所有这些最终都继承来自一个基地 class。这个奇异的基础 class 有许多虚函数,其实现根据所考虑的派生 class 而不同。派生的 classes 也有自己独特的功能。
我在通过 Cython 包装它时遇到了很多麻烦,主要是因为我找不到在每个继承的classes 属于该特定类型(而不是单数基数 class 的类型)。我也尝试过类型转换,以及尝试删除指针然后重新初始化它,但它仍然认为它指向相同的基class。示例代码如下:
inheritTest.pyx:
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()
float Evaluate(float)
bool DataExists()
SetObject(BaseClass *)
cdef class PyBaseClass:
cdef BaseClass *thisptr
def __cinit__(self):
self.thisptr = new BaseClass()
def __dealloc__(self):
del self.thisptr
cdef class PyDerivedClass(PyBaseClass):
#This is one of the solutions that I have tried
def __cinit__(self):
if(self.thisptr):
del self.thisptr
self.thisptr = new DerivedClass()
def __dealloc__(self):
del self.thisptr
def Evaluate(self, time):
#I need to call the Derived implementation of this function, not Base
return self.thisptr.Evaluate(self,time)
def SetObject(self, PyBaseClass inputObject):
#The issue here is that it looks for SetObject to be declared in BaseClass and spits an error otherwise. If I put a empty declaration, the complain is of ambiguous method overload
self.thisptr.SetObject(inputObject.thisptr)
此外,当我在我的 Python 脚本中调用 SetObject 时,我希望能够传入一个 PyDerived 对象作为输入,因为它继承自 PyBase,难道它不应该工作吗?我试过了,错误是:
参数类型不正确:需要 PyBase,得到 PyDerived
希望我的问题有意义,如果您需要任何其他信息,请告诉我:)
而不是删除 self.thisptr
的旧副本,只是让基 class 的构造函数仅在 self
的类型是基 class 时才初始化指针].
def __cinit__(self):
if type(self) is PyBaseClass:
self.thisptr = new BaseClass()
确保在基础 class __dealloc__
方法中也以相同的方式防止释放。
然后,为了避免一堆不必要的转换,在 subclass 包装器中,制作两个不同的属性,一个存储指向转换为基类型的 c++ 对象的指针 class另一个存储指向具有原始类型的 c++ 对象的指针。像这样:
cdef DerivedClass* derivedptr
def __cinit__(self):
self.derivedptr = self.thisptr = new DerivedClass()
然后,当您需要访问派生的方法时class,请改用派生指针。
确保在释放时只删除派生指针。
我从 Cython Users mailing list 上的讨论中得到了这个想法。