This question already has an answer here:
- protected destructor with unique_ptr 2 answers
I want to bind with the class from third party library. The class have some pure virtual functions but the destructor is protected and virtual.
In order to bind the class, I have to write a derived class that overrides the pure virtual functions (https://pybind11.readthedocs.io/en/stable/advanced/classes.html)
so the code is like this
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");
}
However, since the destructor of the base class is declared as protected, the following errors are thrown
error: ‘virtual Parent::~Parent()’ is protected
virtual ~ Parent() //Dtor
I can not modify the base class since it's a third party library.
Any idea to bind the class with pybind11?
std::unique_ptr
andstd::shared_ptr
are smart pointers supported by pybind out of box. Both of them require destructor to be public.The simplest solution would be to write intermediate class with public destructor and expose it with pybind11.
So all your Python classes will inherit from
DeletableParent
If all you want to do is to make Parent-derived classes on Python side, this solution is fine.
If you want to expose a C++ Parent-derived-class which doesn't have
DeletableParent
as one of it's bases you will find difficulties in exposing such diverged inheritance relations.Another option is to write your own smart pointer which does not call destructor of holded pointer. But it looks like straight road to memory leaks.
Update: I overlooked that this particular issue is already covered in pybind11 doc: https://pybind11.readthedocs.io/en/stable/advanced/classes.html#non-public-destructors