从继承的类实例化指向函数的指针

时间:2014-02-07 00:43:11

标签: c++

我正在尝试研究这个Generic object-oriented differential equations integrators class的细节但是我在编译更简单的例子时遇到了一些问题。这个想法是定义一个主类的集成器,所有其他集成方法类都是通过继承派生的。这是实现Euler方法的代码。

//file integrator.hpp
#include <iostream>
#include <vector>
#include <math.h>
#include <complex>
#include <cmath>


template <class C /* a container */, class T> class Integrator{
protected:
C statevector;
T t, h;

// a pointer to the function to be integrated
void (*return_derivs)(const C& x, const T t, C& deriv);//OK, I understand that a pointer to ODEs system is neede.

Integrator (const C&, const T, const T,
        void (*)(const C&, const T, C&)); //Question: why use void(*) in place of void (*return_derivs)?

public:
virtual ~Integrator() { }
virtual void step(void) = 0;
virtual void set_step_size(T new_h) {h = new_h;}

T current_time(void) const {return(t);}
void get_state(C&, T&) const;
};


template <class C, class T, class B /* base type of C */>
class Euler : public Integrator<C,T>
{
private:
  C dxdt;

public:
  Euler (const C &x0, const T t0, const T h_init,
     void (*dxdt_calc)(const C&, const T, C&))
    : Integrator <C,T> (x0, t0, h_init, dxdt_calc),
      dxdt(x0) { }

  void step(void);
};

template <class C, class T, class B>
void Euler<C,T,B>::step(void) // I guess, the resolution of the Integrator class variables id needed. Consequently I modify this part of the code. 
{
  Integrator<C,T>::return_derivs(Integrator<C,T>::statevector,Integrator<C,T>::t,dxdt);
  Integrator<C,T>::statevector += B(Integrator<C,T>::h)*dxdt;
  Integrator<C,T>::t += Integrator<C,T>::h;
}

实例化Euler积分器对象的主程序:

#include <complex>
#include <valarray>
#include "integrator.hpp"
using namespace std;

namespace discretization_data
{
  const complex<double> i(0,1);
  unsigned int nmesh = 10;
}

void discretized_odes(const valarray<complex<double> > &psi,
              const double t, valarray<complex<double> > &dpsidt)
{
  using namespace discretization_data;
  dpsidt[0] = i*(psi[1]-2.0*psi[0]);
  dpsidt[nmesh-1] = i*(psi[nmesh-2]-2.0*psi[nmesh-1]);
  for (int loop=1; loop<nmesh-1; loop++)
    dpsidt[loop] = i*(psi[loop+1] - 2.0*psi[loop]
              + psi[loop-1]);
}

int main()
{
  using namespace discretization_data;
  // Initial conditions
  valarray<complex<double> >
    psi(complex<double>(1.0/nmesh), nmesh);

  Euler<valarray<complex<double> >, double, complex<double> >
    dSchrodinger(psi, 0.0, 0.01, discretized_odes ); //I guess the problem is here.

  while (dSchrodinger.current_time() < 50)
    dSchrodinger.step();
  //Some output statements would be added to a real program...
}

问题是,当我编译示例时,compiller无法找到对积分器对象的引用。但我不知道问题出在哪里?

要编译我使用命令:

g++ integrator.hpp main.cpp -o main.x -lm

获取错误信息:

/tmp/ccre01X7.o: In function `Euler<std::valarray<std::complex<double> >, double, std::complex<double> >::Euler(std::valarray<std::complex<double> > const&, double, double, void (*)(std::valarray<std::complex<double> > const&, double, std::valarray<std::complex<double> >&))':
main.cpp:(.text._ZN5EulerISt8valarrayISt7complexIdEEdS2_EC2ERKS3_ddPFvS6_dRS3_E[_ZN5EulerISt8valarrayISt7complexIdEEdS2_EC5ERKS3_ddPFvS6_dRS3_E]+0x46): undefined reference to `Integrator<std::valarray<std::complex<double> >, double>::Integrator(std::valarray<std::complex<double> > const&, double, double, void (*)(std::valarray<std::complex<double> > const&, double, std::valarray<std::complex<double> >&))'
collect2: error: ld returned 1 exit status

2 个答案:

答案 0 :(得分:0)

假设您发布了完整的代码 - 没有实现:

Integrator (const C&, const T, const T,
        void (*)(const C&, const T, C&)); //Question: why use void(*) in place of void (*return_derivs)?

在您提供的.hpp文件中。由于Integrator是一个类模板,您必须:

  1. 将实现放在头文件中(这将使构造函数内联)
  2. 为某些参数显式实例化Integrator类,并在.cpp文件中为这些特定参数实现构造函数。
  3. 我猜你想要第一个选择。

    至于上面评论中发布的问题 - 不完全确定你在问什么。它是一个构造函数的声明,它接受一个指向函数的指针返回void并接受const C&const T&C&作为参数。它似乎将用于初始化return_derivs。你想如何在一个应该设置它的构造函数中使用变量?

答案 1 :(得分:0)

男孩,那篇CUJ论文很久以前了! tsuki是对的,你错过了Integrator基类的实现。 CUJ很久以前就停止了发布,但是如果你想看到我们的完整代码ftp://ftp.drdobbs.com/sourcecode/cuj/,他们的代码档案仍然可以在Dobb博士的网站上找到。我们的文章发表在2003年11月的期刊上。我还将我们的代码放在我的研究网站上:http://people.uleth.ca/~roussel/data/