1

In a project, I have decided to try to hide all the widget toolkit details behind an abstract factory pattern. The concrete widget toolkit is gtkmm. Here is simple diagram showing the architecture I have so far:

Architecture so far

(So for now, I'm simply trying to abstract stuff away. The factory is not there yet. Eventually, it will construct the Gtkmm3* classes and return the corresponding interface.)

I started trying to abstract away the "containers" or "layout". In my code, I need to operate on the layouts. For example, I need to be able to register widgets in them. Using plain gtkmm, I would use:


void Gtk::Grid::attach(Gtk::Widget& child, int left, int top, int width, int height);

which in the case of my abstractions would translate to something like this:

void ILayout::attach(IWidget& child, int left, int top, int width, int height);

Implementing ILayout::attach is easy. I can simply dynamic_cast the child argument to the Gtk::Widget type and call Gtk::Grid::attach. This is possible because the concrete Gtkmm3Widget class also inherits from Gtk::Widget. In my code, I also need to access the specific elements inside de layout. In gtkmm I used the

Gtk::Widget* Gtk::Grid::get_child_at(int left, int top);

call. In the case of my abstraction, this would translate to:

IWidget* ILayout::get_child_at(int left, int top);

In this case, the implementation is not so simple, because I access a bare Gtk::Widget* but must return a (non owning) IWidget*, of which Gtk::Widget knowns nothing about. Here is the code:

IWidget* Gtkmm3Layout::get_child_at(int left, int top)
{
    Gtk::Widget* gtkWidget = get_child_at(left, top);

    return ???
}

In the above code, if I construct a Gtkmm3Widget instance and return its address, then I will get a dangling pointer because it will be destroyed at the end of the scope.

Questions:

  1. Is there a way to return the needed non-owning Gtk::Widget*?
  2. I don't see any and I'm starting to think I have a design flaw*. If this is the case, what would be a better way to approach this?

* I have found no "real life" example of an implementation of this design pattern I could study. All I find are toy examples.

3
  • 1
    How did the child widget get there in the first place? If it's guaranteed to have been created as an IWidget, you can just dynamic cast again. Did you try that and get nullptr or what? Commented Nov 8, 2023 at 23:37
  • For some reason I thought that this would not work in the opposite direction... But now that you mention it it seems very straightforward... Commented Nov 9, 2023 at 1:12
  • @Useless You were right, using dynamic_cast again worked. I forgot to cast something elsewhere in the code. I should have thought about that. If you want to write an answer, I'll accept it. Commented Nov 10, 2023 at 21:01

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.