www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Simulating multiple inheritance

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
This is related to wrapping wxWidgets.

One issue with the new wxWidgets 2.9.x series is that there seem to be
more multiply-inherited classes than before. In particular some of the
main classes have become MI classes (e.g. wxApp derives from
wxAppConsole which is now an MI class). Some wrappers (like wx.net)
maintain these classes manually and simply discard MI altogether and
make every class a singly-inherited class. SWIG does a similar thing
too. E.g. in wx.net wxApp on the C# side looks like this:

C#:
wxApp -> wxEvtHandler -> wxObject -> IDisposable

Whereas on the C++ side things are a bit more complicated:
wxApp -> wxAppConsole -> wxEvtHandler -> wxObject, ...
                                     -> wxEventFilter -> wxObject, ...

So the wxAppConsole subobject is never really accessed in C#. My
dilemma is whether I should to the same thing as C# and figure out
which classes to skip inheriting from (that does mean doing a little
manual-labor), or maybe implement some sort of MI implementation via
interfaces or 'alias this' tricks (the latter is actually quite buggy
atm.).

A sample implementation:
http://paste.pocoo.org/show/574125/

It's not ideal, if the user wants to use a base type he has to type
"IWxEvtHandler" instead of just "wxEvtHandler" like he would in C++.
It's not an issue with naming, I could name the interface "EvtHandler"
and the class itself "wxEvtHandler", but I think people would probably
forget this distinction.

With 'alias this' tricks the user-code can be much cleaner. A sample
implementation:
http://paste.pocoo.org/show/574131/

Unfortunately 'alias this' has plenty of compiler bugs right now.

I guess what I'm looking for is the most convenient implementation for
user-code. Maybe someone else has experience wrapping C++ libraries or
simulating MI? I am *really* not an expert when it comes to MI.
Mar 31 2012
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-03-31 19:05, Andrej Mitrovic wrote:
 This is related to wrapping wxWidgets.

 One issue with the new wxWidgets 2.9.x series is that there seem to be
 more multiply-inherited classes than before. In particular some of the
 main classes have become MI classes (e.g. wxApp derives from
 wxAppConsole which is now an MI class). Some wrappers (like wx.net)
 maintain these classes manually and simply discard MI altogether and
 make every class a singly-inherited class. SWIG does a similar thing
 too. E.g. in wx.net wxApp on the C# side looks like this:

The first thing that pops up in my mind is using interfaces and template mixins, something like this: http://pastebin.com/jWMKQ6yy -- /Jacob Carlborg
Apr 01 2012
prev sibling next sibling parent bls <bizprac orange.fr> writes:
On 03/31/2012 10:05 AM, Andrej Mitrovic wrote:
 This is related to wrapping wxWidgets.

 One issue with the new wxWidgets 2.9.x series is that there seem to be
 more multiply-inherited classes than before

As Jacob already said mixin templates and Interfaces are the way to go. I think you have to define the mixin template as *mixin* template mixin_name. interface Baz {} mixin template Baz() { // In case that you need to access the parent class alias typeof(this) ThisClass; } class Bar {} class Foo : Bar , Baz { mixin Baz; } Good to know that you are still develop the wxWidget bindings. Keep us informed.
Apr 01 2012
prev sibling parent bls <bizprac orange.fr> writes:
On 03/31/2012 10:05 AM, Andrej Mitrovic wrote:
 One issue with the new wxWidgets 2.9.x series is that there seem to be
 more multiply-inherited classes than before

A bit more complete snippet. interface Foo { void doFoo(); } // Foo implementation mixin template FooMixin() { alias typeof(this) thisClass; void doFoo() { thisClass.init(); } } class Bar { void doFoo() {} } class Baz :Bar, Foo { alias Bar.doFoo BarFoo; mixin FooMixin; void init() {} } hth
Apr 01 2012