实例化指针从继承类函数

instantiating a pointer to function from an inherited class

本文关键字:类函数 继承 指针 实例化      更新时间:2023-10-16

我正在尝试研究这种面向对象的微分方程集成符类的细节,但是我有一些问题可以编译更简单的示例。这个想法是定义一个主要集成符类,从中所有其他集成方法都通过继承得出。这是实现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 Integrator对象实例化的主要程序:

#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...
}

问题是,当我编译示例时,组合器找不到对Integrator对象的引用。但是我不承担问题的位置?

编译我使用命令:

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

获取错误Messaje:

/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

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

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文件中实现这些特定参数的构造函数。

我猜你想要第一个选项。

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

男孩,那个cuj纸很久以前!Tsuki是对的,您缺少集成商基类的实现。Cuj很久以前就停止发布,但是如果您想查看我们的完整代码:ftp://ftp.drdobbs.com/sourceceode/cuj/,他们的代码档案仍然可以在DROBB网站上使用。我们的文章发表在2003年11月的一期中。我还将代码放在我的研究网站上:http://people.uleth.ca/~roussel/data/。