c++ - Cython 和 C++ 继承

标签 c++ python inheritance cython

我有 2 个类,A 和 B。B 继承自 A。

//C++    
class A
{
    public:
        int getA() {return this->a;};
        A() {this->a = 42;}
    private:
        int a;

};

class B: public A
{
    public:
       B() {this->b = 111;};
       int getB() {return this->b;};
    private:
        int b;

};

现在我想使用 Cython 连接这两个类,并可以从 B 实例调用 getA() 方法:

a = PyA()
b = PyB()
assert a.getA() == b.getA()

目前我的 pyx 文件如下所示:

cdef extern from "Inherit.h" :
    cdef cppclass A:
       int getA()

    cdef cppclass B(A):
       int getB()


cdef class PyA:
    cdef A* thisptr

    def __cinit__(self):
       print "in A: allocating thisptr"
       self.thisptr = new A()
    def __dealloc__(self):
       if self.thisptr:
           print "in A: deallocating thisptr"
           del self.thisptr

    def getA(self):
       return self.thisptr.getA()

cdef class PyB(PyA):
    def __cinit__(self):
       if self.thisptr:
          print "in B: deallocating old A"
          del self.thisptr
       print "in B: creating new b"
       self.thisptr = new B()

    def __dealloc__(self):
       if self.thisptr:
           print "in B: deallocating thisptr"
           del self.thisptr
           self.thisptr = <A*>0

    def getB(self):
       return (<B*>self.thisptr).getB()

虽然我希望这段代码不会做任何太危险的事情,但我也希望有更好的方法来处理它。

同样使用模块生成如下输出:

>>> from inherit import *
>>> b = PyB()
in A: allocating thisptr
in B: deallocating old A
in B: creating new b
>>> b.getA()
42
>>> b.getB()
111
>>> del b
in B: deallocating thisptr

而且我真的不喜欢分配一个 A 实例只是为了在之后立即释放它。

关于如何正确执行的任何建议?

最佳答案

我做了一些实验,并且已经准备好了答案,但现在我知道问题出在哪里了:

If your extension type has a base type, the __cinit__ method of the base type is automatically called before your __cinit__ method is called; you cannot explicitly call the inherited __cinit__ method.

所以真正的问题是 Cython 类型仍然没有构造函数,只有预初始化钩子(Hook) __cinit__ 的行为更像默认构造函数。您不能从构造函数调用虚方法,也不能从 __cinit__ 调用它(如果您进行调用,它的行为就像非虚方法)。

__cinit__里面,type(self)返回了正确的类型对象,但是没用。 Cython 没有静态字段,方法和类型对象只能是 type 的实例(没有元类)。 Python @staticmethod 很容易被覆盖,所以没用。

所以没有其他方法可以将分配放在 def __init__(self): 中,并在您使用它的任何地方检查初始化的 thisptr

您可以考虑创建一个全局虚拟 C++ 对象,并将其分配给 thisptr 以避免检查和崩溃。没有后初始化程序 Hook ,因此您将无法检查是否已经进行了正确的初始化。

关于c++ - Cython 和 C++ 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10298371/

相关文章:

c++ - 将 shared_ptr 设置为指向现有对象

c++ - MPI 和 DLL(SO) 函数

python - 在OpenCV VideoCapture或Vidgear中访问/打开嵌入式视频

c++ - 使用继承来添加功能

c++ - 继承:构造函数,像c++11中基类的数组成员一样初始化C

c++ - 没有 IDE 的 Visual Studio 2010

c++ - 为什么 switch 语句不能应用于字符串?

python - 在python中从屏幕中提取文本

python - 忘记从函数返回结果 : how to prevent this bug?

C++ 库 : application inserts a class in inheritance hierarchy