多重继承/虚拟函数 使用Cython(作为接口,因此我可以通过Python调用C++函数),我试图包装一个复杂的C++类层次结构,所有这些结构最终都继承自一个基类。这个奇异基类有许多虚函数,它们的实现与所考虑的派生类不同。派生类也有自己独特的函数

多重继承/虚拟函数 使用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

我在通过Cython包装它时遇到了很多麻烦,主要是因为我找不到一种方法来重新定义每个继承类中的self.thisptr为该特定类型(而不是单一基类的类型)。我也尝试过类型转换,以及尝试删除指针,然后重新初始化它,但它仍然认为它指向相同的基类。示例代码如下:

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时,我希望能够将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对象作为函数输入参数传入,你有什么想法吗?如果你有多个类从同一个基类继承,这肯定会更干净。就清洁度而言,如果有很多类彼此继承,我只需要保留一个基类指针,然后为每个为我执行强制转换的类声明一个属性(命名类似于每个类)。描述如何声明属性。这将避免携带大量不同的指针,但会在每个类中添加几行额外的代码。不过这只是个想法。