Reimplement py::init<...> to use common factory code
This reimplements the py::init<...> implementations using the various
functions added to support `py::init(...)`, and moves the implementing
structs into `detail/init.h` from `pybind11.h`. It doesn't simply use a
factory directly, as this is a very common case and implementation
without an extra lambda call is a small but useful optimization.
This, combined with the previous lazy initialization, also avoids
needing placement new for `py::init<...>()` construction: such
construction now occurs via an ordinary `new Type(...)`.
A consequence of this is that it also fixes a potential bug when using
multiple inheritance from Python: it was very easy to write classes
that double-initialize an existing instance which had the potential to
leak for non-pod classes. With the new implementation, an attempt to
call `__init__` on an already-initialized object is now ignored. (This
was already done in the previous commit for factory constructors).
This change exposed a few warnings (fixed here) from deleting a pointer
to a base class with virtual functions but without a virtual destructor.
These look like legitimate warnings that we shouldn't suppress; this
adds virtual destructors to the appropriate classes.
diff --git a/tests/test_multiple_inheritance.py b/tests/test_multiple_inheritance.py
index 80b6dae..475dd3b 100644
--- a/tests/test_multiple_inheritance.py
+++ b/tests/test_multiple_inheritance.py
@@ -73,7 +73,8 @@
class MI4(MI3, m.Base2):
def __init__(self, i, j):
MI3.__init__(self, i, j)
- # m.Base2 is already initialized (via MI2)
+ # This should be ignored (Base2 is already initialized via MI2):
+ m.Base2.__init__(self, i + 100)
class MI5(m.Base2, B1, m.Base1):
def __init__(self, i, j):