minor fixes to PR #368

This commit is contained in:
Wenzel Jakob 2016-08-28 02:03:15 +02:00
parent a3906778eb
commit 5e4e477b8b
2 changed files with 14 additions and 20 deletions

View File

@ -947,32 +947,30 @@ within pybind11.
Classes with non-public destructors Classes with non-public destructors
=================================== ===================================
If a class has a private or protected destructor, as might be the case in a singleton If a class has a private or protected destructor (as might e.g. be the case in
pattern for example, a compile error will occur when trying to expose the class because a singleton pattern), a compile error will occur when creating bindings via
the std::unique_ptr holding the instance of the class will attempt to call its destructor pybind11. The underlying issue is that the ``std::unique_ptr`` holder type that
when de-allocating the instance. In order to expose classes with private or protected is responsible for managing the lifetime of instances will reference the
destructors you can override the ``holder_type`` and provide a custom destructor. Pybind11 destructor even if no deallocations ever take place. In order to expose classes
provides a blank destructor for you to use as follows with private or protected destructors, it is possible to override the holder
type via the second argument to ``class_``. Pybind11 provides a helper class
``py::nodelete`` that disables any destructor invocations. In this case, it is
crucial that instances are deallocated on the C++ side to avoid memory leaks.
.. code-block:: cpp .. code-block:: cpp
/* ... definition ... */ /* ... definition ... */
class MyClass { class MyClass {
~MyClass() {} private:
~MyClass() { }
}; };
/* ... binding code ... */ /* ... binding code ... */
py::class_<MyClass, std::unique_ptr<MyClass, py::blank_deleter<MyClass>>(m, "MyClass") py::class_<MyClass, std::unique_ptr<MyClass, py::nodelete>>(m, "MyClass")
.def(py::init<>) .def(py::init<>)
The blank destructor provided by Pybind11 is a no-op, so you will still need to make sure
you are cleaning up the memory in C++. Additionally, the blank destructor, or any custom
destructor you provide to the unique_ptr will only be called if the object is initialized
within Python. If the object is initialized in C++ via a getter function, the deleter will
not be called at all.
.. _catching_and_throwing_exceptions: .. _catching_and_throwing_exceptions:
Catching and throwing exceptions Catching and throwing exceptions

View File

@ -350,11 +350,7 @@ PYBIND11_DECL_FMT(float, "f");
PYBIND11_DECL_FMT(double, "d"); PYBIND11_DECL_FMT(double, "d");
PYBIND11_DECL_FMT(bool, "?"); PYBIND11_DECL_FMT(bool, "?");
// Helper class for exposing classes with a private destructor by overriding the deleter object of std::unique_ptr /// Dummy destructor wrapper that can be used to expose classes with a private destructor
template <typename T> struct nodelete { template <typename T> void operator()(T*) { } };
struct blank_deleter
{
void operator()(T*) {}
};
NAMESPACE_END(pybind11) NAMESPACE_END(pybind11)