summaryrefslogtreecommitdiff
path: root/ext/pybind11/docs/advanced/classes.rst
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pybind11/docs/advanced/classes.rst')
-rw-r--r--ext/pybind11/docs/advanced/classes.rst45
1 files changed, 34 insertions, 11 deletions
diff --git a/ext/pybind11/docs/advanced/classes.rst b/ext/pybind11/docs/advanced/classes.rst
index 4a423b578..8896441b6 100644
--- a/ext/pybind11/docs/advanced/classes.rst
+++ b/ext/pybind11/docs/advanced/classes.rst
@@ -79,7 +79,7 @@ helper class that is defined as follows:
PYBIND11_OVERLOAD_PURE(
std::string, /* Return type */
Animal, /* Parent class */
- go, /* Name of function */
+ go, /* Name of function in C++ (must match Python name) */
n_times /* Argument(s) */
);
}
@@ -90,7 +90,8 @@ functions, and :func:`PYBIND11_OVERLOAD` should be used for functions which have
a default implementation. There are also two alternate macros
:func:`PYBIND11_OVERLOAD_PURE_NAME` and :func:`PYBIND11_OVERLOAD_NAME` which
take a string-valued name argument between the *Parent class* and *Name of the
-function* slots. This is useful when the C++ and Python versions of the
+function* slots, which defines the name of function in Python. This is required
+when the C++ and Python versions of the
function have different names, e.g. ``operator()`` vs ``__call__``.
The binding code also needs a few minor adaptations (highlighted):
@@ -115,11 +116,20 @@ The binding code also needs a few minor adaptations (highlighted):
}
Importantly, pybind11 is made aware of the trampoline helper class by
-specifying it as an extra template argument to :class:`class_`. (This can also
+specifying it as an extra template argument to :class:`class_`. (This can also
be combined with other template arguments such as a custom holder type; the
order of template types does not matter). Following this, we are able to
define a constructor as usual.
+Bindings should be made against the actual class, not the trampoline helper class.
+
+.. code-block:: cpp
+
+ py::class_<Animal, PyAnimal /* <--- trampoline*/> animal(m, "Animal");
+ animal
+ .def(py::init<>())
+ .def("go", &PyAnimal::go); /* <--- THIS IS WRONG, use &Animal::go */
+
Note, however, that the above is sufficient for allowing python classes to
extend ``Animal``, but not ``Dog``: see ref:`virtual_and_inheritance` for the
necessary steps required to providing proper overload support for inherited
@@ -186,7 +196,7 @@ example as follows:
virtual std::string go(int n_times) = 0;
virtual std::string name() { return "unknown"; }
};
- class Dog : public class Animal {
+ class Dog : public Animal {
public:
std::string go(int n_times) override {
std::string result;
@@ -220,6 +230,13 @@ override the ``name()`` method):
std::string bark() override { PYBIND11_OVERLOAD(std::string, Dog, bark, ); }
};
+.. note::
+
+ Note the trailing commas in the ``PYBIND11_OVERLOAD`` calls to ``name()``
+ and ``bark()``. These are needed to portably implement a trampoline for a
+ function that does not take any arguments. For functions that take
+ a nonzero number of arguments, the trailing comma must be omitted.
+
A registered class derived from a pybind11-registered class with virtual
methods requires a similar trampoline class, *even if* it doesn't explicitly
declare or override any virtual methods itself:
@@ -228,7 +245,8 @@ declare or override any virtual methods itself:
class Husky : public Dog {};
class PyHusky : public Husky {
- using Dog::Dog; // Inherit constructors
+ public:
+ using Husky::Husky; // Inherit constructors
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, Husky, go, n_times); }
std::string name() override { PYBIND11_OVERLOAD(std::string, Husky, name, ); }
std::string bark() override { PYBIND11_OVERLOAD(std::string, Husky, bark, ); }
@@ -242,11 +260,13 @@ follows:
.. code-block:: cpp
template <class AnimalBase = Animal> class PyAnimal : public AnimalBase {
+ public:
using AnimalBase::AnimalBase; // Inherit constructors
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, AnimalBase, go, n_times); }
std::string name() override { PYBIND11_OVERLOAD(std::string, AnimalBase, name, ); }
};
template <class DogBase = Dog> class PyDog : public PyAnimal<DogBase> {
+ public:
using PyAnimal<DogBase>::PyAnimal; // Inherit constructors
// Override PyAnimal's pure virtual go() with a non-pure one:
std::string go(int n_times) override { PYBIND11_OVERLOAD(std::string, DogBase, go, n_times); }
@@ -373,7 +393,9 @@ crucial that instances are deallocated on the C++ side to avoid memory leaks.
/* ... binding code ... */
py::class_<MyClass, std::unique_ptr<MyClass, py::nodelete>>(m, "MyClass")
- .def(py::init<>)
+ .def(py::init<>())
+
+.. _implicit_conversions:
Implicit conversions
====================
@@ -422,11 +444,11 @@ The section on :ref:`properties` discussed the creation of instance properties
that are implemented in terms of C++ getters and setters.
Static properties can also be created in a similar way to expose getters and
-setters of static class attributes. It is important to note that the implicit
-``self`` argument also exists in this case and is used to pass the Python
-``type`` subclass instance. This parameter will often not be needed by the C++
-side, and the following example illustrates how to instantiate a lambda getter
-function that ignores it:
+setters of static class attributes. Note that the implicit ``self`` argument
+also exists in this case and is used to pass the Python ``type`` subclass
+instance. This parameter will often not be needed by the C++ side, and the
+following example illustrates how to instantiate a lambda getter function
+that ignores it:
.. code-block:: cpp
@@ -478,6 +500,7 @@ to Python.
.def(py::self += py::self)
.def(py::self *= float())
.def(float() * py::self)
+ .def(py::self * float())
.def("__repr__", &Vector2::toString);
return m.ptr();