I am trying to make a system like Java's swing
, where you have a window, and that window has multiple components, such as Labels (text/images), Text Boxes, Check Boxes, etc. The way swing
works is that there is a Component
class, which is abstract, which has an abstract paint method, which draws the component, and some other methods. The actual window (JFrame
) has a list (of sorts) of all of the components in the window. These components' actual types are unknown, but they all extend the Component
class.
My Window
class:
class Window {
public:
...
template<typename T, typename std::enable_if<std::is_base_of<Component, T>::value>::type* = nullptr> T addComponent(T component);
private:
...
std::vector<Component> components;
...
};
Component
:
class Component {
public:
...
virtual void paintComponent() = 0;
...
};
Somewhere along the line, this code is called:
for each (Component c in components) {
c.paintComponent();
}
However, I cannot make an object of type Component
, because it is abstract, although the actual objects would be other types that extend Component
and have their own paintComponent()
method. For methods (Window::addComponent()
), I can use
template<typename T, typename std::enable_if<std::is_base_of<Component, T>::value>::type* = nullptr> T
however, this does not work for variables.
So, my question is, How do I make an object of an abstract type, i.e. how do I make a Component
object (or an object that extends Component, but whose actual type is unknown)?
Thanks in advance!
You can't instantiate a type of a abstract class. You have to refer to it through a pointer. This will force you to do manual memory management. So using a smart pointer like
shared_ptr
orunique_ptr
can help reduce headaches. Using pointers would make your vector look like thisand then in your loop you would call it like this
This way you can use
Component
for any type that derives from it.Also, if Component is going to be used like this it should have a virtual destructor. This will make sure that the correct destructor is called if it deleted through a pointer to a
Component
. This would make the destructor declaration look like this