github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/docs/advanced/smart_ptrs.rst (about) 1 Smart pointers 2 ############## 3 4 std::unique_ptr 5 =============== 6 7 Given a class ``Example`` with Python bindings, it's possible to return 8 instances wrapped in C++11 unique pointers, like so 9 10 .. code-block:: cpp 11 12 std::unique_ptr<Example> create_example() { return std::unique_ptr<Example>(new Example()); } 13 14 .. code-block:: cpp 15 16 m.def("create_example", &create_example); 17 18 In other words, there is nothing special that needs to be done. While returning 19 unique pointers in this way is allowed, it is *illegal* to use them as function 20 arguments. For instance, the following function signature cannot be processed 21 by pybind11. 22 23 .. code-block:: cpp 24 25 void do_something_with_example(std::unique_ptr<Example> ex) { ... } 26 27 The above signature would imply that Python needs to give up ownership of an 28 object that is passed to this function, which is generally not possible (for 29 instance, the object might be referenced elsewhere). 30 31 std::shared_ptr 32 =============== 33 34 The binding generator for classes, :class:`class_`, can be passed a template 35 type that denotes a special *holder* type that is used to manage references to 36 the object. If no such holder type template argument is given, the default for 37 a type named ``Type`` is ``std::unique_ptr<Type>``, which means that the object 38 is deallocated when Python's reference count goes to zero. 39 40 It is possible to switch to other types of reference counting wrappers or smart 41 pointers, which is useful in codebases that rely on them. For instance, the 42 following snippet causes ``std::shared_ptr`` to be used instead. 43 44 .. code-block:: cpp 45 46 py::class_<Example, std::shared_ptr<Example> /* <- holder type */> obj(m, "Example"); 47 48 Note that any particular class can only be associated with a single holder type. 49 50 One potential stumbling block when using holder types is that they need to be 51 applied consistently. Can you guess what's broken about the following binding 52 code? 53 54 .. code-block:: cpp 55 56 class Child { }; 57 58 class Parent { 59 public: 60 Parent() : child(std::make_shared<Child>()) { } 61 Child *get_child() { return child.get(); } /* Hint: ** DON'T DO THIS ** */ 62 private: 63 std::shared_ptr<Child> child; 64 }; 65 66 PYBIND11_MODULE(example, m) { 67 py::class_<Child, std::shared_ptr<Child>>(m, "Child"); 68 69 py::class_<Parent, std::shared_ptr<Parent>>(m, "Parent") 70 .def(py::init<>()) 71 .def("get_child", &Parent::get_child); 72 } 73 74 The following Python code will cause undefined behavior (and likely a 75 segmentation fault). 76 77 .. code-block:: python 78 79 from example import Parent 80 81 print(Parent().get_child()) 82 83 The problem is that ``Parent::get_child()`` returns a pointer to an instance of 84 ``Child``, but the fact that this instance is already managed by 85 ``std::shared_ptr<...>`` is lost when passing raw pointers. In this case, 86 pybind11 will create a second independent ``std::shared_ptr<...>`` that also 87 claims ownership of the pointer. In the end, the object will be freed **twice** 88 since these shared pointers have no way of knowing about each other. 89 90 There are two ways to resolve this issue: 91 92 1. For types that are managed by a smart pointer class, never use raw pointers 93 in function arguments or return values. In other words: always consistently 94 wrap pointers into their designated holder types (such as 95 ``std::shared_ptr<...>``). In this case, the signature of ``get_child()`` 96 should be modified as follows: 97 98 .. code-block:: cpp 99 100 std::shared_ptr<Child> get_child() { return child; } 101 102 2. Adjust the definition of ``Child`` by specifying 103 ``std::enable_shared_from_this<T>`` (see cppreference_ for details) as a 104 base class. This adds a small bit of information to ``Child`` that allows 105 pybind11 to realize that there is already an existing 106 ``std::shared_ptr<...>`` and communicate with it. In this case, the 107 declaration of ``Child`` should look as follows: 108 109 .. _cppreference: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this 110 111 .. code-block:: cpp 112 113 class Child : public std::enable_shared_from_this<Child> { }; 114 115 .. _smart_pointers: 116 117 Custom smart pointers 118 ===================== 119 120 pybind11 supports ``std::unique_ptr`` and ``std::shared_ptr`` right out of the 121 box. For any other custom smart pointer, transparent conversions can be enabled 122 using a macro invocation similar to the following. It must be declared at the 123 top namespace level before any binding code: 124 125 .. code-block:: cpp 126 127 PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>); 128 129 The first argument of :func:`PYBIND11_DECLARE_HOLDER_TYPE` should be a 130 placeholder name that is used as a template parameter of the second argument. 131 Thus, feel free to use any identifier, but use it consistently on both sides; 132 also, don't use the name of a type that already exists in your codebase. 133 134 The macro also accepts a third optional boolean parameter that is set to false 135 by default. Specify 136 137 .. code-block:: cpp 138 139 PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>, true); 140 141 if ``SmartPtr<T>`` can always be initialized from a ``T*`` pointer without the 142 risk of inconsistencies (such as multiple independent ``SmartPtr`` instances 143 believing that they are the sole owner of the ``T*`` pointer). A common 144 situation where ``true`` should be passed is when the ``T`` instances use 145 *intrusive* reference counting. 146 147 Please take a look at the :ref:`macro_notes` before using this feature. 148 149 By default, pybind11 assumes that your custom smart pointer has a standard 150 interface, i.e. provides a ``.get()`` member function to access the underlying 151 raw pointer. If this is not the case, pybind11's ``holder_helper`` must be 152 specialized: 153 154 .. code-block:: cpp 155 156 // Always needed for custom holder types 157 PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>); 158 159 // Only needed if the type's `.get()` goes by another name 160 namespace PYBIND11_NAMESPACE { namespace detail { 161 template <typename T> 162 struct holder_helper<SmartPtr<T>> { // <-- specialization 163 static const T *get(const SmartPtr<T> &p) { return p.getPointer(); } 164 }; 165 }} 166 167 The above specialization informs pybind11 that the custom ``SmartPtr`` class 168 provides ``.get()`` functionality via ``.getPointer()``. 169 170 .. seealso:: 171 172 The file :file:`tests/test_smart_ptr.cpp` contains a complete example 173 that demonstrates how to work with custom reference-counting holder types 174 in more detail.