pybind11 中受保护的虚拟析构函数
protected virtual destructor in pybind11
我想与来自第三方库的 class 绑定。 class 有一些纯虚函数,但析构函数是受保护的和虚拟的。
为了绑定 class,我必须编写一个派生的 class 来覆盖纯虚函数 (https://pybind11.readthedocs.io/en/stable/advanced/classes.html)
所以代码是这样的
class Parent {
public:
virtual void foo() = 0;
protected:
virtual ~ Parent() //Dtor
{
}
};
class PyParent : public Parent
{
public:
void foo () override {
PYBIND11_OVERLOAD_PURE(
void,
Parent,
foo
);
}
};
void init(py::module & m) {
py::class_<Parent, PyParent> p(m, "p");
}
但是,由于基class的析构函数被声明为protected,所以抛出如下错误
error: ‘virtual Parent::~Parent()’ is protected
virtual ~ Parent() //Dtor
我无法修改基础 class,因为它是第三方库。
是否知道将 class 与 pybind11 绑定?
std::unique_ptr
和 std::shared_ptr
是 pybind 开箱即用支持的智能指针。它们都要求析构函数是 public。
最简单的解决方案是使用 public 析构函数编写中间 class 并使用 pybind11 公开它。
...
class DeletableParent : public Parent{
public:
~DeletableParent() override = default;
};
...
py::class_<DeletableParent, PyParent> p(m, "p");
所以你所有的 Python class 都会继承自 DeletableParent
如果您只想在Python 侧创建Parent-derived classes,这个解决方案就可以了。
如果您想公开一个没有 DeletableParent
作为其基础之一的 C++ Parent-derived-class,您会发现公开这种不同的继承关系很困难。
另一种选择是编写您自己的智能指针,它不调用持有指针的析构函数。但它看起来像是通往内存泄漏的直路。
更新:
我忽略了这个特殊问题已经包含在 pybind11 文档中:
https://pybind11.readthedocs.io/en/stable/advanced/classes.html#non-public-destructors
我想与来自第三方库的 class 绑定。 class 有一些纯虚函数,但析构函数是受保护的和虚拟的。
为了绑定 class,我必须编写一个派生的 class 来覆盖纯虚函数 (https://pybind11.readthedocs.io/en/stable/advanced/classes.html)
所以代码是这样的
class Parent {
public:
virtual void foo() = 0;
protected:
virtual ~ Parent() //Dtor
{
}
};
class PyParent : public Parent
{
public:
void foo () override {
PYBIND11_OVERLOAD_PURE(
void,
Parent,
foo
);
}
};
void init(py::module & m) {
py::class_<Parent, PyParent> p(m, "p");
}
但是,由于基class的析构函数被声明为protected,所以抛出如下错误
error: ‘virtual Parent::~Parent()’ is protected
virtual ~ Parent() //Dtor
我无法修改基础 class,因为它是第三方库。
是否知道将 class 与 pybind11 绑定?
std::unique_ptr
和 std::shared_ptr
是 pybind 开箱即用支持的智能指针。它们都要求析构函数是 public。
最简单的解决方案是使用 public 析构函数编写中间 class 并使用 pybind11 公开它。
...
class DeletableParent : public Parent{
public:
~DeletableParent() override = default;
};
...
py::class_<DeletableParent, PyParent> p(m, "p");
所以你所有的 Python class 都会继承自 DeletableParent
如果您只想在Python 侧创建Parent-derived classes,这个解决方案就可以了。
如果您想公开一个没有 DeletableParent
作为其基础之一的 C++ Parent-derived-class,您会发现公开这种不同的继承关系很困难。
另一种选择是编写您自己的智能指针,它不调用持有指针的析构函数。但它看起来像是通往内存泄漏的直路。
更新: 我忽略了这个特殊问题已经包含在 pybind11 文档中: https://pybind11.readthedocs.io/en/stable/advanced/classes.html#non-public-destructors