2014-02-07 60 views
0

我想研究這個Generic object-oriented differential equations integrators class的細節,但我有一些問題編譯更簡單的例子。這個想法定義了一類主要的集成器,其中所有其他集成方法類都是通過繼承派生的。這裏是實施歐拉方法的代碼。實例化一個函數指針從繼承類

//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; 
} 

其中歐拉積分器對象被實例化的主程序:

#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 

獲取錯誤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 
+0

請介紹迄今爲止您一直在調試的[testcase](http://sscce.org)。 –

+0

*編譯器*找不到引用?或***鏈接器***找不到它。發佈您收到的**完整**錯誤消息。 – WhozCraig

回答

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文件中的這些特定參數。

我猜你想要第一個選項。

至於上面評論中發佈的問題 - 不完全確定你在問什麼。它是一個構造函數的聲明,它接受一個函數指針返回void並接受const C&const T&C&作爲參數。看來它會被用來初始化return_derivs。你想如何在應該設置它的構造函數中使用變量?

+0

我不知道。正如引用的參考文獻中所建議的那樣,我正在按照引用的參考文獻試圖使工作實現Integrators類。 – user3116936

0

男孩,那CUJ紙很久以前了! tsuki是對的,你錯過了Integrator基類的實現。 CUJ在很久以前就停止發佈了,但是如果您想查看我們的完整代碼,他們的代碼檔案仍然可以在Dr Dobb博士的網站上找到:ftp://ftp.drdobbs.com/sourcecode/cuj/。我們的文章出現在2003年11月刊。我還將我們的代碼放在我的研究網站上:http://people.uleth.ca/~roussel/data/

+0

非常感謝您的幫助。 – user3116936

+0

再次感謝您的回答。 – user3116936