diff --git a/docs/advanced.rst b/docs/advanced.rst index f719c8075..a48ebd87b 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -470,10 +470,6 @@ can now create a python class that inherits from ``Dog``: See the file :file:`example-virtual-functions.cpp` for complete examples using both the duplication and templated trampoline approaches. - The file also contains a more intrusive approach using multiple - inheritance, which may be useful in special situations with deep class - hierarchies to avoid code generation. - .. _macro_notes: General notes regarding convenience macros diff --git a/example/example-virtual-functions.cpp b/example/example-virtual-functions.cpp index 924427afa..d08c782af 100644 --- a/example/example-virtual-functions.cpp +++ b/example/example-virtual-functions.cpp @@ -82,20 +82,12 @@ void runExampleVirtVirtual(ExampleVirt *ex) { } -// Inheriting virtual methods. We do three versions here: the repeat-everything version and the -// templated trampoline versions mentioned in docs/advanced.rst, and also another version using -// multiple inheritance. +// Inheriting virtual methods. We do two versions here: the repeat-everything version and the +// templated trampoline versions mentioned in docs/advanced.rst. // -// This latter approach has the advantage of generating substantially less code for deep -// hierarchies, but it requires intrusive changes of changing the wrapped classes to using virtual -// inheritance, which itself requires constructor rewriting for any non-default virtual base class -// constructors (most problematic is that constructors cannot be effectively inherited from a -// virtual base class). The example is kept here because it does work, and may be useful in limited -// cases, but the non-instrusive templated version is generally preferred. -// -// These base classes are all exactly the same (aside from the virtual inheritance for the MI -// version), but we technically need distinct classes for this example code because we need to be -// able to bind them properly (pybind11, sensibly, doesn't allow us to bind the same C++ class to +// These base classes are exactly the same, but we technically need distinct +// classes for this example code because we need to be able to bind them +// properly (pybind11, sensibly, doesn't allow us to bind the same C++ class to // multiple python classes). class A_Repeat { #define A_METHODS \ @@ -129,13 +121,6 @@ class D_Repeat : public C_Repeat { D_METHODS }; -// Base classes for multiple inheritance trampolines; note the added "virtual" inheritance. The -// classes are otherwise identical. -class A_MI { A_METHODS }; -class B_MI : virtual public A_MI { B_METHODS }; -class C_MI : virtual public B_MI { C_METHODS }; -class D_MI : virtual public C_MI { D_METHODS }; - // Base classes for templated inheritance trampolines. Identical to the repeat-everything version: class A_Tpl { A_METHODS }; class B_Tpl : public A_Tpl { B_METHODS }; @@ -213,31 +198,6 @@ public: }; */ -// Inheritance approach 3: multiple inheritance with virtual base class inheritance. This requires -// declaration and compilation of exactly 7 methods (one per virtual method declaration or -// override), versus the 11 required above. On the other hand, if we need anything other than -// default constructors, this quickly becomes painful, and so this is of limited use. -class PyA_MI : virtual public A_MI { -public: - // Can't inherit constructors: we would have to duplicate constructors with an explicit - // initializer for each virtual base, which is a pain for anything but the default constructor. - int unlucky_number() override { PYBIND11_OVERLOAD_PURE(int, A_MI, unlucky_number, ); } - void say_something(unsigned times) override { PYBIND11_OVERLOAD(void, A_MI, say_something, times); } -}; -class PyB_MI : public PyA_MI, virtual public B_MI { -public: - void say_something(unsigned times) override { PYBIND11_OVERLOAD(void, B_MI, say_something, times); } - double lucky_number() { PYBIND11_OVERLOAD(double, B_MI, lucky_number, ); } - int unlucky_number() { PYBIND11_OVERLOAD(int, B_MI, unlucky_number, ); } -}; -class PyC_MI : public PyB_MI, virtual public C_MI { -public: - int unlucky_number() override { PYBIND11_OVERLOAD(int, C_MI, unlucky_number, ); } - double lucky_number() override { PYBIND11_OVERLOAD(double, C_MI, lucky_number, ); } -}; -class PyD_MI : public PyC_MI, virtual public D_MI { -}; - void initialize_inherited_virtuals(py::module &m) { // Method 1: repeat @@ -266,19 +226,6 @@ void initialize_inherited_virtuals(py::module &m) { py::class_, PyB_Tpl>(m, "D_Tpl", py::base()) .def(py::init<>()); - // Method 3: MI - py::class_, PyA_MI>(m, "A_MI") - .def(py::init<>()) - .def("unlucky_number", &A_MI::unlucky_number) - .def("say_something", &A_MI::say_something); - py::class_, PyB_MI>(m, "B_MI", py::base()) - .def(py::init<>()) - .def("lucky_number", &B_MI::lucky_number); - py::class_, PyC_MI>(m, "C_MI", py::base()) - .def(py::init<>()); - py::class_, PyD_MI>(m, "D_MI", py::base()) - .def(py::init<>()); - }; diff --git a/example/example-virtual-functions.py b/example/example-virtual-functions.py index 9b175fbce..1f7196570 100644 --- a/example/example-virtual-functions.py +++ b/example/example-virtual-functions.py @@ -4,7 +4,7 @@ import sys sys.path.append('.') from example import ExampleVirt, runExampleVirt, runExampleVirtVirtual, runExampleVirtBool -from example import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_MI, B_MI, C_MI, D_MI, A_Tpl, B_Tpl, C_Tpl, D_Tpl +from example import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_Tpl, B_Tpl, C_Tpl, D_Tpl class ExtendedExampleVirt(ExampleVirt): def __init__(self, state): @@ -40,11 +40,6 @@ sys.stdout.flush() class VI_AR(A_Repeat): def unlucky_number(self): return 99 -class VI_AMI(A_MI): - def unlucky_number(self): - return 990 - def say_something(self, times): - return A_MI.say_something(self, 2*times) class VI_AT(A_Tpl): def unlucky_number(self): return 999 @@ -52,17 +47,11 @@ class VI_AT(A_Tpl): class VI_CR(C_Repeat): def lucky_number(self): return C_Repeat.lucky_number(self) + 1.25 -class VI_CMI(C_MI): - def lucky_number(self): - return 1.75 class VI_CT(C_Tpl): pass class VI_CCR(VI_CR): def lucky_number(self): return VI_CR.lucky_number(self) * 10 -class VI_CCMI(VI_CMI): - def lucky_number(self): - return VI_CMI.lucky_number(self) * 100 class VI_CCT(VI_CT): def lucky_number(self): return VI_CT.lucky_number(self) * 1000 @@ -73,11 +62,6 @@ class VI_DR(D_Repeat): return 123 def lucky_number(self): return 42.0 -class VI_DMI(D_MI): - def unlucky_number(self): - return 1230 - def lucky_number(self): - return -9.5 class VI_DT(D_Tpl): def say_something(self, times): print("VI_DT says:" + (' quack' * times)) @@ -87,12 +71,12 @@ class VI_DT(D_Tpl): return -4.25 classes = [ - # A_Repeat, A_MI, A_Tpl, # abstract (they have a pure virtual unlucky_number) - VI_AR, VI_AMI, VI_AT, - B_Repeat, B_MI, B_Tpl, - C_Repeat, C_MI, C_Tpl, - VI_CR, VI_CMI, VI_CT, VI_CCR, VI_CCMI, VI_CCT, - D_Repeat, D_MI, D_Tpl, VI_DR, VI_DMI, VI_DT + # A_Repeat, A_Tpl, # abstract (they have a pure virtual unlucky_number) + VI_AR, VI_AT, + B_Repeat, B_Tpl, + C_Repeat, C_Tpl, + VI_CR, VI_CT, VI_CCR, VI_CCT, + D_Repeat, D_Tpl, VI_DR, VI_DT ] for cl in classes: diff --git a/example/example-virtual-functions.ref b/example/example-virtual-functions.ref index aab8f310c..795f7b03f 100644 --- a/example/example-virtual-functions.ref +++ b/example/example-virtual-functions.ref @@ -14,10 +14,6 @@ VI_AR: hihihi Unlucky = 99 -VI_AMI: -hihihihihihi -Unlucky = 990 - VI_AT: hihihi Unlucky = 999 @@ -27,11 +23,6 @@ B says hi 3 times Unlucky = 13 Lucky = 7.00 -B_MI: -B says hi 3 times -Unlucky = 13 -Lucky = 7.00 - B_Tpl: B says hi 3 times Unlucky = 13 @@ -42,11 +33,6 @@ B says hi 3 times Unlucky = 4444 Lucky = 888.00 -C_MI: -B says hi 3 times -Unlucky = 4444 -Lucky = 888.00 - C_Tpl: B says hi 3 times Unlucky = 4444 @@ -57,11 +43,6 @@ B says hi 3 times Unlucky = 4444 Lucky = 889.25 -VI_CMI: -B says hi 3 times -Unlucky = 4444 -Lucky = 1.75 - VI_CT: B says hi 3 times Unlucky = 4444 @@ -72,11 +53,6 @@ B says hi 3 times Unlucky = 4444 Lucky = 8892.50 -VI_CCMI: -B says hi 3 times -Unlucky = 4444 -Lucky = 175.00 - VI_CCT: B says hi 3 times Unlucky = 4444 @@ -87,11 +63,6 @@ B says hi 3 times Unlucky = 4444 Lucky = 888.00 -D_MI: -B says hi 3 times -Unlucky = 4444 -Lucky = 888.00 - D_Tpl: B says hi 3 times Unlucky = 4444 @@ -102,11 +73,6 @@ B says hi 3 times Unlucky = 123 Lucky = 42.00 -VI_DMI: -B says hi 3 times -Unlucky = 1230 -Lucky = -9.50 - VI_DT: VI_DT says: quack quack quack Unlucky = 1234