2013-10-30 83 views
0

首先我知道這在C++中是不可能的。但我希望有人能說出解決我的問題的方法。我有一個類,它代表了一個數學函數:引用成員函數

class myClass: 
{ 
private: 
public: 
    myClass() {}; 
    double value(double, double){ /* doing some complicated calculation here */} }; 
    double integrate { /*calc*/ return integral; }; 
} 

integrate()我想創建一個以value()參考一個結構。該結構的定義如下:

struct gsl_monte_function_struct { 
    double (*f)(double * x_array, size_t dim, void * params); 
    size_t dim; 
    void * params; 
}; 

(我需要這個結構從GSL調用蒙特卡洛積分程序)

前面已經說過,我知道這是用C++禁止。但有沒有可能使用myClass的成員函數gsl_monte_function_struct?如果myClass不可能自我整合,是否可以從value()以外的地方撥打gsl_monte_function_struct作爲參考?提前致謝!

回答

0

好吧,我發現了兩種解決方案:

1)(通用解決方案)使用抽象基類,它具有指向當前實例的靜態指針和調用派生類的函數的靜態函數。靜態函數可以與函數指針一起使用。

實施例:

struct gsl_monte{ 
    double (*f)(double y); 
}; 

class myBase { 
private: 
    static myBase* instance; 

public: 
    myBase(){}; 
    static void setInstance(myBase* newOne); 
    virtual double value(double x) =0; 
    static double callValue(double x);//{return value(x);} 
}; 

class myClass : public myBase { 
    public: 
     myClass(){}; 
     double value(double x) { return x; }; 
}; 

myBase* myBase::instance = new myClass(); 
double myBase::callValue(double x){return instance->value(x);} 
void myBase::setInstance(myBase* newOne){instance=newOne;}; 

double g(double xx) {return xx;}; 

int main(int argc, char** argv){ 
    double x[2]; x[0]=1.3; x[1]=1.3; 
    myClass* instance = new myClass(); 
    myBase::setInstance(instance); 
    instance->value(3); 
    std::cout << "Test " << myBase::callValue(5) << std::endl; 
    gsl_monte T; 
    T.f=&myBase::callValue; 
    double (*f)(double y, void*) = &myBase::callValue; 
} 

2)(溶液特定於我的問題)Fortunatly所需功能接受一個參數指針,我可以使用通過當前對象:

#include <iostream> 
#include <functional> 
using namespace std::placeholders; 

struct gsl_monte{ 
    double (*f)(double y, void*); 
}; 

class myClass { 
    public: 
     myClass(){}; 
     double value(double x) { return x; }; 
}; 

double valueTT(double x, void* param) { return static_cast<myClass*>(param)->value(x); }; 

int main(int argc, char** argv){ 
    double x[2]; x[0]=1.3; x[1]=1.3; 
    myClass* instance = new myClass(); 
    instance->value(3); 
    gsl_monte T; 
    T.f=&valueTT; 
    double (*f)(double y, void*) = &valueTT; 
} 
1

如果明白你的意思,你需要一個指向myClass成員函數的指針。

double (myClass::*value)(double,double) 

此功能可以在以後的實例作爲被稱爲:您可以通過聲明的成員函數指針爲實現這一

(instance.*value)(x,y); 

或者您可以使用std::bind創建一個函數對象可以是稱爲普通功能,而不必跟蹤在調用std::bind後調用的實例:

auto& value = std::bind(myClass::value, instance); 
// .... 
value(x,y); 
+0

它應該是注意到調用該成員函數指針將需要指向成員的語法,例如' - > *'。在幾個問題和答案中有這樣的例子。 – WhozCraig

+0

@WhozCraig這是一個很好的觀點。這就是爲什麼我將std :: bind提到能夠避免它的原因。 – Agentlien

+0

感謝您的回答:我試過:'auto d = std :: bind(&myClass :: value,instance,std :: placeholders :: _ 1);'。這工作!但現在我想要做的:'double(* f)(double y)= d;'(這是gsl_monte_function的成員函數)。這失敗了!有任何想法嗎? – hansgans