我正在创建一个按钮类,并且很难在两种解决方案之间做出决定。
1)对Button
类进行模板化,并在按下按钮时在其构造函数中调用一个函数对象。我正在编码的人担心这会导致代码膨胀/颠簸。
2)创建一个ButtonAction基类,每个按钮都有一个不同的ButtonAction。因此,Button
类在其构造函数中使用ButtonAction来按下按钮时调用。
我们也考虑过使用函数指针,但还没有仔细考虑过。
答案 0 :(得分:5)
您可以使用boost::function<>
个对象进行操作。这样您就不需要任何模板,按钮类变得非常灵活:
struct Button {
typedef boost::function<void ()> action_t;
action_t action;
Button(const action_t &a_action) : action(a_action) {
}
void click() {
action();
}
};
这样,类很容易使用函数指针,仿函数对象或boost::bind之类的东西:
void dosomething();
Button b1 = Button(&dosomething);
struct SomeAction {
void operator()() {}
};
Button b2 = Button(SomeAction());
答案 1 :(得分:1)
我列举了每种方案的后果,然后决定哪种方案最适合手头的特定情况。
如果模板选项可能(过早担心?)膨胀对象代码,那么多态替代可能会使源代码变得不必要地复杂。
对于模板,编译器将为您实例化的每个函数对象创建另一个Button
类。这意味着产品对象代码将比您通过子类接受各种操作对象的单个Button
类更大。
在多态的情况下,编译器将生成单个Button
类,但您现在将拥有另一个要维护的基类,并且您将被强制将其子类化为您添加到集合中的任何新操作。特别是,您将无法使用在创建基本操作类之前编写的操作,除非您可以修改它们,以便它们派生自该操作类。
模板替代方案允许您使用符合模板界面的任何内容。因此,如果您将模板参数用作函数,那么您可以接受任何可以像函数一样调用的内容。这意味着您甚至不需要考虑函数指针的替代方法,因为模板允许您接受函数指针 - 以及更多。
多态性选项意味着编译器会更多地了解您要执行的操作。换句话说,模板会出现模板错误。
如果您可以找到仅模板Button
成员函数的方法,而不是整个Button
类,则可以缓解一些模板问题。将函数参数作为模板的实例,因此您无需显式实例化模板函数。然后,您将获得一些模板优势以及一些多态性优势。