diff --git a/docs/advanced/classes.rst b/docs/advanced/classes.rst index 1a1648d338..ea23287d8b 100644 --- a/docs/advanced/classes.rst +++ b/docs/advanced/classes.rst @@ -64,7 +64,7 @@ helper class that is defined as follows: .. code-block:: cpp - class PyAnimal : public Animal { + class PyAnimal : public Animal, py::trampoline_self_life_support { public: /* Inherit the constructors */ using Animal::Animal; @@ -89,7 +89,8 @@ practice to always use the base class, in combination with .. note:: For completeness, the base class has no effect if a holder other than ``py::smart_holder`` used, including the default ``std::unique_ptr``. - Please think twice, though, the pitfalls are very real. + Please think twice, though, the pitfalls are very real, and the overhead + for using the safer ``py::smart_holder`` is very likely to be in the noise. The macro :c:macro:`PYBIND11_OVERRIDE_PURE` should be used for pure virtual functions, and :c:macro:`PYBIND11_OVERRIDE` should be used for functions which have @@ -106,11 +107,11 @@ The binding code also needs a few minor adaptations (highlighted): :emphasize-lines: 2,3 PYBIND11_MODULE(example, m) { - py::class_(m, "Animal") + py::class_(m, "Animal") .def(py::init<>()) .def("go", &Animal::go); - py::class_(m, "Dog") + py::class_(m, "Dog") .def(py::init<>()); m.def("call_go", &call_go); @@ -127,7 +128,7 @@ Bindings should be made against the actual class, not the trampoline helper clas .. code-block:: cpp :emphasize-lines: 3 - py::class_(m, "Animal"); + py::class_(m, "Animal"); .def(py::init<>()) .def("go", &Animal::go); /* <--- DO NOT USE &PyAnimal::go HERE */ @@ -136,32 +137,6 @@ extend ``Animal``, but not ``Dog``: see :ref:`virtual_and_inheritance` for the necessary steps required to providing proper overriding support for inherited classes. -To enable safely passing a ``std::unique_ptr`` to a trampoline object between -Python and C++, - -1. the C++ type (``Animal`` above) must be wrapped with - ``py::class_<..., py::smart_holder>`` (see :ref:`smart_holder`), and - -2. the trampoline helper class must inherit from - ``py::trampoline_self_life_support``. - -I.e. the example above needs these two changes: - -.. code-block:: cpp - - class PyAnimal : public Animal, public py::trampoline_self_life_support { - ... - }; - -.. code-block:: cpp - - py::class_(m, "Animal"); - -.. seealso:: - - A fairly minimal but complete example is in - :file:`tests/test_class_sh_trampoline_unique_ptr.cpp`. - The Python session below shows how to override ``Animal::go`` and invoke it via a virtual method call. @@ -281,13 +256,13 @@ override the ``name()`` method): .. code-block:: cpp - class PyAnimal : public Animal { + class PyAnimal : public Animal, py::trampoline_self_life_support { public: using Animal::Animal; // Inherit constructors std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Animal, go, n_times); } std::string name() override { PYBIND11_OVERRIDE(std::string, Animal, name, ); } }; - class PyDog : public Dog { + class PyDog : public Dog, py::trampoline_self_life_support { public: using Dog::Dog; // Inherit constructors std::string go(int n_times) override { PYBIND11_OVERRIDE(std::string, Dog, go, n_times); } @@ -309,7 +284,7 @@ declare or override any virtual methods itself: .. code-block:: cpp class Husky : public Dog {}; - class PyHusky : public Husky { + class PyHusky : public Husky, py::trampoline_self_life_support { public: using Husky::Husky; // Inherit constructors std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Husky, go, n_times); } @@ -324,13 +299,15 @@ follows: .. code-block:: cpp - template class PyAnimal : public AnimalBase { + template + class PyAnimal : public AnimalBase, py::trampoline_self_life_support { public: using AnimalBase::AnimalBase; // Inherit constructors std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, AnimalBase, go, n_times); } std::string name() override { PYBIND11_OVERRIDE(std::string, AnimalBase, name, ); } }; - template class PyDog : public PyAnimal { + template + class PyDog : public PyAnimal, py::trampoline_self_life_support { public: using PyAnimal::PyAnimal; // Inherit constructors // Override PyAnimal's pure virtual go() with a non-pure one: @@ -348,9 +325,9 @@ The classes are then registered with pybind11 using: .. code-block:: cpp - py::class_> animal(m, "Animal"); - py::class_> dog(m, "Dog"); - py::class_> husky(m, "Husky"); + py::class_, py::smart_holder> animal(m, "Animal"); + py::class_, py::smart_holder> dog(m, "Dog"); + py::class_, py::smart_holder> husky(m, "Husky"); // ... add animal, dog, husky definitions Note that ``Husky`` did not require a dedicated trampoline template class at @@ -536,12 +513,12 @@ an alias: // ... virtual ~Example() = default; }; - class PyExample : public Example { + class PyExample : public Example, py::trampoline_self_life_support { public: using Example::Example; PyExample(Example &&base) : Example(std::move(base)) {} }; - py::class_(m, "Example") + py::class_(m, "Example") // Returns an Example pointer. If a PyExample is needed, the Example // instance will be moved via the extra constructor in PyExample, above. .def(py::init([]() { return new Example(); })) @@ -1142,7 +1119,7 @@ described trampoline: virtual int foo() const { return 42; } }; - class Trampoline : public A { + class Trampoline : public A, py::trampoline_self_life_support { public: int foo() const override { PYBIND11_OVERRIDE(int, A, foo, ); } }; @@ -1152,7 +1129,7 @@ described trampoline: using A::foo; }; - py::class_(m, "A") // <-- `Trampoline` here + py::class_(m, "A") // <-- `Trampoline` here .def("foo", &Publicist::foo); // <-- `Publicist` here, not `Trampoline`! Binding final classes diff --git a/docs/advanced/misc.rst b/docs/advanced/misc.rst index a0438f0330..3aeb8ab9d3 100644 --- a/docs/advanced/misc.rst +++ b/docs/advanced/misc.rst @@ -80,7 +80,7 @@ could be realized as follows (important changes highlighted): .. code-block:: cpp :emphasize-lines: 8,30,31 - class PyAnimal : public Animal { + class PyAnimal : public Animal, py::trampoline_self_life_support { public: /* Inherit the constructors */ using Animal::Animal; @@ -98,12 +98,12 @@ could be realized as follows (important changes highlighted): }; PYBIND11_MODULE(example, m) { - py::class_ animal(m, "Animal"); + py::class_ animal(m, "Animal"); animal .def(py::init<>()) .def("go", &Animal::go); - py::class_(m, "Dog", animal) + py::class_(m, "Dog", animal) .def(py::init<>()); m.def("call_go", [](Animal *animal) -> std::string {