考虑到抽象工厂模式,假设你有一个class hierarchy具体工厂覆盖createButton * s *虚方法,需要返回更多的按钮。有什么可以解决这个问题的优雅解决方法,因为C ++只支持协变返回类型?的dynamic_cast?
GoF示例的修改版本符合我的要求:
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(){
}
};
应用程序框架:
Application(GUIFactory * factory) {
Button* buttons = factory->createButtons();
for(...) {...}
}
答案 0 :(得分:2)
无法做到。问问自己,来电者是delete
还是delete[]
?他们如何知道阵列中有多少元素?使用原始指针返回无法解决这些问题。所以对你的问题的简单回答是,这是不可能做到的,你甚至不想这样做。被调用者需要知道返回类型 - 无论是一个按钮还是多个按钮,以及如何在完成后清理它们。
如果不调用未定义的行为,您甚至无法访问非首位元素。
工厂应该构建单个对象。如果您需要多个,请多次调用出厂功能。
即使你神奇地拥有可以同时处理多个按钮的代码,当他们只期望一个(wtf?)时,你需要安全地返回多个按钮。这意味着std::vector<smart_pointer<Button>>
。
答案 1 :(得分:1)
您不想要在工厂方法中创建数组并返回指向客户端的指针。这样你就可以不知道有多少个按钮,所以你真的无法做任何事情。
在C ++ 11中,您可以返回std::vector<shared_ptr<Button>>
甚至std::vector<unique_ptr<Button>>
。
我可能会选择这个解决方案:返回某种自定义的“readonly”Button
集合,它暴露了计数和索引器,仅此而已。如果适合您的场景,可以添加迭代器。
class ButtonCollection
{
public:
size_t getCount() const {}
Button& getAt(size_t index) {}
const Button& getAt(size_t index) const {}
private:
friend class GUIFactory;
ButtonCollection() {}
add(Button* button) {}
// Or in C++11:
// add(std::unique_ptr<Button> button) {}
};
使用您的应用程序框架:
Application(GUIFactory& factory)
{
std::auto_ptr<ButtonCollection> buttons = factory.createButtons();
// Or in C++11:
//std::unique_ptr<ButtonCollection> buttons = factory.createButtons();
for(...) {...}
}
答案 2 :(得分:0)
考虑使用boost::ptr_vector
或boost::ptr_array
http://www.boost.org/doc/libs/1_48_0/libs/ptr_container/doc/ptr_vector.html