2014-01-22 78 views
1

我有一个当前的代码工作很好。我想让它的一部分更有效率。C++通过函数指针来模板函数

我有一堂课,Foo,和一大堆Foo的子类做不同的事情(在这个例子中,我使用Bar作为唯一的子类)。

我定义在它的构造,宣布了一系列step是我的主要程序的每个循环迭代中Bar“更新”如何。这很酷,因为我可以添加多个step,每个运行迭代次数不同。

问题是,将一个step添加到Bar的过程是多余的,我想让它变得更少。

这里是我的类声明如下所示:

template <class T> 
class Step { 
    public: 
     Step(); 
     void (T::*fnPtr)(); // function to execute when step is run within a Foo 
     int count;   // number of iterations to execute on 
} 

class Foo { 
    public: 
     Foo(); 
     void doSomething(); 

     template <class T> 
     void addStep(Step<T>* newStep) { 
      // adds a new step to a linked list 
     } 
} 

class Bar : public Foo { 
    public: 
     Bar(); 
     void doAnotherThing(); 
     void doYetAnotherThing(); 
     void omgAnotherThing(); 
} 

Bar构造会是这个样子:

Bar::Bar() { 
    // ah four lines of code (at least!) every time I want to add a step! 

    Step<Bar>* a = new Step<Bar>; 
    a->fnPtr = &Bar::doAnotherThing; 
    a->count = 10; 
    addStep(a); 

    Step<Bar>* b = new Step<Bar>; 
    b->fnPtr = &Bar::doYetAnotherThing; 
    b->count = 20; 
    addStep(b); 

    Step<Bar>* c = new Step<Bar>; 
    c->fnPtr = &Bar::omgAnotherThing; 
    c->count = 6; 
    addStep(c); 
} 

理想情况下,我想了Bar的一步创作的样子有点像这个:

Bar::Bar() { 
    // very nice! I like! 

    addANewStep(&Bar::doAnotherThing,10); 
    addANewStep(&Bar::doYetAnotherThing,20); 
    addANewStep(&Bar::omgAnotherThing,30); 
} 

但我不是很确定,特别是如何将&Bar::doAnotherThing传递给函数。

有什么建议吗?

回答

1

您可以实现addANewStep方法以下列方式(Foo类,因为我明白的):

template <class T> 
void addANewStep(void (T::*fnPtr)(), int count) 
{ 
    Step<T>* step = new Step<T>; 

    step->fnPtr = fnPtr; 
    step->count = count; 
    addStep(step); 
} 

而且不要忘记类定义后分号。

+0

最简单的办法取代Step<T>,到目前为止。非常好。 –

+0

@RyanTuck:真的!向Step添加构造函数。它应该做什么开始。 –

0
class Foo { 
     std::vector< 
      std::pair<std::function<void()>, int> 
     > m_steps; 
    public: 
     Foo(); 
     void doSomething(); 

     template <class F> 
     void addStep(F callback, int count) { 
      // add step 
      m_steps.emplace_back(callback, count); 
     } 
} 

调用函数:

addStep(std::bind(&Bar::doAnotherThing, this), 10); 

传递this是neccessary所以仿知道上哪一个实例成员函数被调用。

0

简单的第一个Step是为Step添加构造函数。

template<typename T> 
class Step { 
    public: 
     typedef void (T::*Action)(); 

     Step(Action a, int c): action(a), count(c) {} 
     Action action;   // function to execute when step is run within a Foo 
     int  count;   // number of iterations to execute on 
}; 

现在你的电话是:

addANewStep(new Step(&Bar::doAnotherThing,10)); 
addANewStep(new Step(&Bar::doYetAnotherThing,20)); 
addANewStep(new Step(&Bar::omgAnotherThing,30)); 

然后我们注意到所有新的呼叫。没有与产生的指针关联的所有权语义。我们可以将std::unique_ptr<Step>添加到组合中。但是,这个类就是这么简单,我认为最好的解决方法就是使界面采取步骤对象:

因此改变我想看看addStep()

  template <class T> 
     void addStep(Step<T>* newStep); 

我们看到您正在使用指针,因为你没有一个同质的接口(所以需要指针)。但界面很简单,所以我仍然将其作为一个对象传递,并将所有内存管理内部转换为Foo类(我可以选择std::unique_ptr<Step<T>>作为替代方案)。

  template <class T> 
     void addStep(Step<T> const& newStep) { 
      pointer_container.push_back(new Step<T>(newStep)); 
     } 

这使得你的电话是这样的:

addANewStep(Step(&Bar::doAnotherThing,10)); 
addANewStep(Step(&Bar::doYetAnotherThing,20)); 
addANewStep(Step(&Bar::omgAnotherThing,30)); 

现在,您只需要确保pointer_container采取指针的所有权。

下一步我会采取的是看看如果你可以用std::function<void()>