多重继承/虚拟函数 使用Cython(作为接口,因此我可以通过Python调用C++函数),我试图包装一个复杂的C++类层次结构,所有这些结构最终都继承自一个基类。这个奇异基类有许多虚函数,它们的实现与所考虑的派生类不同。派生类也有自己独特的函数
我在通过Cython包装它时遇到了很多麻烦,主要是因为我找不到一种方法来重新定义每个继承类中的self.thisptr为该特定类型(而不是单一基类的类型)。我也尝试过类型转换,以及尝试删除指针,然后重新初始化它,但它仍然认为它指向相同的基类。示例代码如下: inheritTest.pyx:多重继承/虚拟函数 使用Cython(作为接口,因此我可以通过Python调用C++函数),我试图包装一个复杂的C++类层次结构,所有这些结构最终都继承自一个基类。这个奇异基类有许多虚函数,它们的实现与所考虑的派生类不同。派生类也有自己独特的函数,python,c++,inheritance,virtual,cython,Python,C++,Inheritance,Virtual,Cython,我在通过Cython包装它时遇到了很多麻烦,主要是因为我找不到一种方法来重新定义每个继承类中的self.thisptr为该特定类型(而不是单一基类的类型)。我也尝试过类型转换,以及尝试删除指针,然后重新初始化它,但它仍然认为它指向相同的基类。示例代码如下: inheritTest.pyx: cdef extern from "BaseClass.h": cdef cppclass BaseClass: BaseClass() except + void S
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时,我希望能够将PyDerivated对象作为输入传入,因为它继承自PyBase,难道它不应该工作吗?我试过了,错误是:
参数的类型不正确:应为PyBase,而应为Py派生
希望我的问题有意义,如果您需要任何其他信息,请告诉我:)而不是删除
self的旧副本。thisptr
,只要使基类的构造函数仅在self
的类型是基类时初始化指针即可
def __cinit__(self):
if type(self) is PyBaseClass:
self.thisptr = new BaseClass()
确保在基类\uuuu dealoc\uuuu
方法中也以同样的方式防止释放
然后,为了避免一堆不必要的转换,在子类包装器中,创建两个不同的属性,一个存储指向C++类对象的指针,并将其存储到C++类对象的指针中,并将指针存储到其原始类型的C++对象中。大概是这样的:
cdef DerivedClass* derivedptr
def __cinit__(self):
self.derivedptr = self.thisptr = new DerivedClass()
然后,当需要访问派生类的方法时,请改用派生指针
确保在解除分配时,只删除派生指针
我从上的讨论中得到了这个想法。所以我尝试了上面的解决方案,它在构建时给了我错误,因为它仍然认为它是基类*指针。例如,该错误为:**类型为BaseClass的对象没有属性SetObject**我有一个临时的类型转换解决方案,但我更希望有一个清理器solution@jeet.m更新解释了如何处理所有类型转换。嗯…这是个好主意,如果我有一系列派生类,这难道不意味着我需要为派生的每个阶段/级别重新声明一种新类型的“derivedptr”吗?(即derivedptr1、derivedptr2等)。如果是这样,您认为这是一个比类型铸造更清洁的解决方案吗?只是想知道你认为什么是更好的解决方案,不要怀疑你的答案:)太好了,它很有效,非常感谢!关于我问题的第二部分,关于能够将PyDerivedClass对象作为函数输入参数传入,你有什么想法吗?如果你有多个类从同一个基类继承,这肯定会更干净。就清洁度而言,如果有很多类彼此继承,我只需要保留一个基类指针,然后为每个为我执行强制转换的类声明一个属性(命名类似于每个类)。描述如何声明属性。这将避免携带大量不同的指针,但会在每个类中添加几行额外的代码。不过这只是个想法。