Reputation: 5309
I'm creating a UI system for my OpenGL application and I have this design...
The UI manager:
class UIManager {
public:
UIElement *add(UIElement *element);
}
Example element:
class Button : public UIElement {
public:
Button(UIElement *parent, const string &caption, const Point &position);
}
Now everytime I want to instantiate a button and keep the pointer to it, I'll have to write this:
// somewhere in the header file
UIManager *manager;
Button *button1, *button2;
// in cpp
button1 = static_cast<Button *>(manager->add(new Button(0, "Enter", Point(10, 10))));
button2 = static_cast<Button *>(manager->add(new Button(0, "Exit", Point(10, 50))));
which looks a bit lengthy to me, especially when I have a dozen of elements.
Is this a bad design? Is there another way to get over this?
Upvotes: 0
Views: 116
Reputation: 42942
You can assign the buttons to the variables inside the argument to add:
// somewhere in the header file
UIManager *manager;
Button *button1, button2;
manager->add(button1 = new Button(0, "Enter", Point(10, 10)));
manager->add(button2 = new Button(0, "Exit", Point(10, 50)));
Also remove the returned argument from the add method.
Upvotes: 2
Reputation: 227618
You can declate add
as a template method, and avoid all casting:
class UIManager {
public:
template<typename T>
T* add(T *element) {
// do something with element
return element;
}
}
Then your client code becomes
button1 = manager->add(new Button(0, "Enter", Point(10, 10)));
Upvotes: 2
Reputation: 157504
Declare the add
method as a method template forwarding to the actual method:
class UIManager {
public:
UIElement *add(UIElement *element);
template<typename T> T *add(T *element) {
return static_cast<T *>(add(static_cast<UIElement *>(element))); }
}
Button *button1 = manager->add(new Button(0, "Enter", Point(10, 10)));
Note that instead of raw pointers you should be using managed pointers (unique_ptr
or, in this case, shared_ptr
).
Upvotes: 0