mirror of
https://github.com/pybind/pybind11.git
synced 2026-05-03 13:11:39 +00:00
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.
This commit is contained in:
@@ -148,6 +148,7 @@ class NCVirtTrampoline : public NCVirt {
|
||||
struct Base {
|
||||
/* for some reason MSVC2015 can't compile this if the function is pure virtual */
|
||||
virtual std::string dispatch() const { return {}; };
|
||||
virtual ~Base() = default;
|
||||
};
|
||||
|
||||
struct DispatchIssue : Base {
|
||||
@@ -259,6 +260,7 @@ TEST_SUBMODULE(virtual_functions, m) {
|
||||
virtual std::string &str_ref() { return v; }
|
||||
virtual A A_value() { return a; }
|
||||
virtual A &A_ref() { return a; }
|
||||
virtual ~OverrideTest() = default;
|
||||
};
|
||||
|
||||
class PyOverrideTest : public OverrideTest {
|
||||
@@ -311,6 +313,7 @@ public: \
|
||||
return say_something(1) + " " + std::to_string(unlucky_number()); \
|
||||
}
|
||||
A_METHODS
|
||||
virtual ~A_Repeat() = default;
|
||||
};
|
||||
class B_Repeat : public A_Repeat {
|
||||
#define B_METHODS \
|
||||
@@ -335,7 +338,7 @@ D_METHODS
|
||||
};
|
||||
|
||||
// Base classes for templated inheritance trampolines. Identical to the repeat-everything version:
|
||||
class A_Tpl { A_METHODS };
|
||||
class A_Tpl { A_METHODS; virtual ~A_Tpl() = default; };
|
||||
class B_Tpl : public A_Tpl { B_METHODS };
|
||||
class C_Tpl : public B_Tpl { C_METHODS };
|
||||
class D_Tpl : public C_Tpl { D_METHODS };
|
||||
|
||||
Reference in New Issue
Block a user