Having in mind the abstract factory pattern, imagine that you have a class hierarchy where concrete factories override a createButton*s* virtual method, needing to return a wider array of buttons. What could be an elegant workaround to resolve this, as C++ supports only covariant return types? dynamic_cast?
A modified version of GoF's example to fit my requirement:
class Button {
public:
virtual void paint() = 0;
virtual ~Button(){
}
};
class WinButton: public Button {
public:
void paint() {
cout << "I'm a WinButton";
}
};
class OSXButton: public Button {
public:
void paint() {
cout << "I'm an OSXButton";
}
};
class GUIFactory {
public:
virtual Button * createButtons() = 0;
virtual ~GUIFactory(){
}
};
class WinFactory: public GUIFactory {
public:
WinButton* createButtons() {
return new WinButton[2];
}
~WinFactory(){
}
};
class OSXFactory: public GUIFactory {
public:
OSXButton* createButtons() {
return new OSXButton[2];
}
~OSXFactory(){
}
};
And the application skeleton:
Application(GUIFactory * factory) {
Button* buttons = factory->createButtons();
for(...) {...}
}
It cannot be done. Ask yourself, will the caller delete
or delete[]
it? How will they know how many elements are in the arrays? There's no way to solve either of these problems with a raw pointer return. So the simple answer to your question is that this cannot be done, nor should you even want to. The callee needs to know the return type- whether it's one button or many, and how to clean them up when he's done.
You can't even access the non-first element without invoking Undefined Behaviour.
A Factory is supposed to construct individual objects. If you need more than one, call the factory function more than once.
Even if you magically had code that could deal with more than one button at once when they were expecting just one (wtf?), you need to safely return more than one. That means std::vector<smart_pointer<Button>>
.