Web lists-archives.com

Help with Gtkmm and diamond inheritance pattern

I'm writing a C++ application and I want it to provide a generic UI interface, which under the hood might be using GTK, Win32, etc. The goal is that the app can be compiled with support for one or more UI backends and the user can choose one at runtime, or at least that one backend can be selected at compile time without changing the rest of the app.

So far I have a class UI with subclasses:
Class Widget (abstract base class)
Class Container: public Widget (abstract base for widgets which contain and arrange other widgets)
Class Window: public Container (top-level window)
Class Display: public Widget (displays an image)
(I can't seem to get my phone to not write class with a capital there)

The app would use this something like:

UI::someSpecificBackend ui(argc, argv);
UI::Window win("some title");
UI::Display display();

(Maybe not exactly like this, but roughly.)

Obviously this looks pretty similar to GTK, so I thought it should be pretty simple to implement this backend:
Class GTK::UI: public UI, public Gtk::Application;
Class GTK::UI::Widget: public UI::Widget, public Gtk::Widget;
Class GTK::UI::Container: public UI::Container, public Gtk::Container;
Class GTK::UI::Window: public UI::Window, public Gtk::Window;
Class GTK::UI::Display: public UI::Display, public Gtk::Box;

The problem I run into is that the inheritance graph becomes a big mess and the compiler can't make sense of it. GTK::UI::Window inherits Gtk::Widget multiple times (through GTK::UI::Container, GTK::UI::Widget, Gtk::Window, and Gtk::Container), leading to ambiguity, and it seems like virtual inheritance doesn't help because some of those inheritance paths go through a few layers in Gtkmm. (I can have Gtk::Window be virtual inherited by GTK::UI::Window, but Gtk::Window and Gtk::Container both still non-virtually inherit Gtk::Widget.) So I'm really not sure how to make this work. Maybe I'm approaching it completely wrong?

gtk-devel-list mailing list