我一直在努力学习更多关于泛型编程的知识,因为我认为我对它的了解还不够。所以我在考虑如何实现我的一个程序的模板版本。 我尝试使用的程序是一个数值积分器程序,用户可以在其中选择要使用的积分器(即 Euler、Runge Kutta 等),然后积分他们选择的任何函数。 我目前执行此操作的方法是使用一个名为 Integrator 的抽象基类,以及几个实现集成方法的派生类。 所以代码看起来像这样(还有更多内容,但这只是为了展示方法论)。请注意,我为此使用 Qt 并声明一个 Integrator *integrator;在 MainWindow 类中。
void MainWindow::on_integrateButton_clicked() {
string whichIntegrator = getUserChoice();
integrator = getIntegrator( whichIntegrator, whichFunction, order );
integrator->setUp( data ); // things like initial conditions, time, step size, etc...
runIntegratorInNewThread();
}
getIntegrator 本质上是使用工厂方法
// x being current data, xdot being the results of evaluating derivatives
typedef void (*pFunction)(const double t, const double x[], double *xdot);
Integrator* getIntegrator( const string &whichIntegrator, pFunction whichFunction, int order ) {
if (whichIntegrator == "Euler") {
return new Euler(whichFunction, order);
} else if (whichIntegrator == "RungeKutta") {
return new RungeKutta(whichFunction, order);
}
}
所以这个方法很好用,集成器程序运行的很好。现在我知道模板函数是在编译时生成的,并且鉴于我使用的是运行时信息,您将如何使用模板来实现它?如果问题不明确,我要问的是...在运行时给定用户选择,即使用哪个集成器,我如何使用模板方法调用正确的集成函数?
最佳答案
模板不是 Elixir ,虽然您可以用它们做很多事情,但不要低估您当前使用的多态性的力量。
这可以用模板来完成吗?答案是肯定的,使用 C++11 和 shared_ptr 看起来像这样:
template<class T>
std::shared_ptr<T> getIntegrator(pFunction whichFunction, int order)
{
return std::make_shared<T>(whichFunction, order);
}
在你的来电者中:
std::shared_ptr<Integrator> integrator;
if (whichIntegrator == "Euler")
{
integrator = getIntegrator<Euler>(whichFunction, order);
}
else if(whichIntegrator == "RungeKutta")
{
integrator = getIntegrator<RungeKutta>(whichFunction, order);
}
另外一个注意事项,你应该非常小心这里的内存泄漏,你正在更新和反对,如果你从不释放它,你就会有泄漏。
综上所述,我希望这个答案表明虽然您可以使用模板,但在这种情况下我不推荐它,多态性在这里很有效。 这个例子只是在一个非常简单和冗余的情况下展示了模板的作用
关于C++。模板和运行时用户信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15688452/