我有一个抽象类Shape
(来自C ++代码),我为它做了一个包装器,所以我可以从Python继承这个抽象类。除了一些内存管理问题,一切都很好。在仍然存在ShapeWrapper
C ++对象的情况下,Python对象被创建和销毁。基本上对象被破坏,因为在Python中没有对它的引用,但是在C ++中有对包装类的引用所以我的想法是wrapper
类增加了初始化时的引用计数并且会减少计数C ++包装器类ShapeWrap
被破坏时的析构函数。但似乎这并没有发生在这里。这是一些代码:
Shape
类(用C ++编写):
struct Shape {
virtual inline string get_name() const = 0;
};
ShapeWrap
类:
struct ShapeWrap : public Shape, public wrapper<Shape> {
string get_name() const override {
if (auto py_func = this->get-override("get_name")) {
return py_func();
}
return "Default String";
}
}
我用这种方式定义类:
class_<ShapeWrap, shared_ptr<ShapeWrap>, boost::noncopyable>("Shape")
.def("get_name", pure_virtual(&Shape::get_name));
现在我在这里有一个小功能来取一个Shape并打印出它的名字:
void print_name(shared_ptr<ShapeWrap> shape) {
cout << shape->get_name() << endl;
}
在Python的土地上,我这样做:
class Circle(Shape):
def __init__(self):
super(Circle, self).__init__()
print('Created')
def __del__(self):
print('Destroyed')
def get_name(self):
return "blah"
print_name(Circle())
这就是我得到的
Created
blah
Destroyed
但如果我这样做:
shared_ptr<ShapeWrap> create_shape(const object& cb) {
return extract<shared_ptr<ShapeWrap>>(cb())();
}
在Python中执行此操作:
print_name(create_shape(lambda: Circle()))
我得到了
Created
Destroyed
RuntimeError: Pure virtual function called
如果我在ShapeWrap
的构造函数和析构函数中添加cout,我会得到这个
C++ Constructor
Created
Destroyed
RuntimeError: Pure virtual function called
C++ Destructor
请注意,纯虚拟事物的发生是因为Python对象被销毁,因此没有覆盖方法,因此包装器会调用基本实现,这是一种引发RuntiemError异常的方法。