2013-12-23 109 views
2

我有一個類指針傳遞到一個類方法,如函數參數

class A{ 
    A(/*constructor arguments*/); 
    double MethA(double); 
}; 

我要傳遞的方法MethA中,需要一個指向函數的函數:

double function(double (*f)(double), double x){ 
    return f(x); 
} 

所以我正在做的是打電話

A a(/*constructor arguments*/); 
function(a.MethA,1.0); 

但它不編譯。

我很確定這個問題是在別的地方回答的,但我找不到在哪裏,因爲我不確定我使用的術語是否正確。我是否想通過一個類方法的指針作爲函數參數?或者,傳遞一個函數指針作爲類的成員......我很困惑:-(

+1

請拼寫正確。 'class'是小寫字母,最後需要分號。細節,但編程是關於細節。 –

+0

爲什麼寫代碼充其量是不可理解的?你有虛擬功能。傳入一個具有其中一個的對象,並使代碼可讀 –

+0

指向成員函數的指針具有與函數指針不同的類型 –

回答

2

當你需要使用一個成員函數指針,你需要通過兩個不同的東西:

  • 叫什麼成員函數和
  • 什麼實例來調用它的。

在C++中,你不能在一個結構將它們組合起來,就像你想:

A a; 
bar(a.foo); 

是無效的C++。

相反,你必須這樣做:

A a; 
bar(a, &A::foo) 

並據此申報和實施巴():

void bar(A &a, void (A::*method)()) { 
    a.*method(); 
} 
+0

通過包裝(a。*方法)()在parens酒吧的身體中得到這個工作。 – braitsch

0

它必須是一個靜態函數!

#include <iostream> 
#include <cassert> 
class A { 
public: 
    static double MethA(double x) { return 5 * x; } 
}; 
typedef double (*ftype)(double); 
double function(ftype f) { 
    assert(f != NULL); 
    return f(7); 
} 
int main(int, char**) { 
    // expect "35\n" on stdout 
    std::cout << function(A::MethA) << "\n"; 
} 

它必須是靜態的,因爲你可以「T訪問任何一個的變量不知道一個對象你指到如果需要的非靜態成員變量,你需要一個一個的引用傳遞到靜態函數:

#include <iostream> 
#include <cassert> 
class A { 
    double fX; 
public: 
    A(double x) : fX(x) { } 
    double methB(double x) const { return fX * x; } 
    static double MethB(double x, const A& a) { 
    return a.methB(x); 
    } 
}; 
typedef double (*ftype2)(double, const A&); 
double function_with_context(ftype2 f, const A& a) { 
    assert(f != NULL); 
    return f(7, a); 
} 

int main(int, char**) { 
    A a(6); 
    // expect "42\n" on stdout 
    std::cout << function_with_context(A::MethB, a) << "\n"; 
} 

但它的有時更好地使用繼承和多態來實現這種接口:

#include <iostream> 
class MyInterface { 
public: 
    virtual double f(double x) const = 0; 
}; 

class A : public MyInterface { 
    double fX; 
public: 
    A(double x) : fX(x) { } 
    double f(double x) const { 
    return fX * x; 
    } 
}; 

double function(const MyInterface& o) { 
    return o.f(7); 
} 

int main(int, char**) { 
    A a(6); 
    // expect "42\n" on stdout 
    std::cout << function(a) << "\n"; 
} 
+0

沒關係,這個解決方案適用於我......但我不明白將方法聲明爲靜態的效果。編程好嗎?如果我的課程是課堂模板,它會起作用嗎? – PinkFloyd

+0

這意味着你不能訪問任何A的變量。畢竟,你指的是哪一個對象? –

1

請參閱Arkadiy's答案如果你想看看如何正確使用成員函數指針。

的要求,在意見:如果編譯器使用的是支持lambda表達式(一些不完整的C++ 11做的)。你可以做如下的事情,看起來更像你試圖使用的語法。

您的function改變爲類似的定義:

template <typename F> 
double function(F f, double x){ 
    return f(x); 
}; 

接受一個參數,是調用了double函數模板。

在您的調用點你這樣做:

A a(/*constructor arguments*/); 
function([&](double x){return a.MethA(x);},1.0); 

這產生就地一個函數對象由參考綁定到您的類的實例a

該模板可以用<type_traits>中的一些魔法制作成完全類型安全的,但是如果你傳遞了一些非常錯誤的東西,它會給你模板溢出。

+0

我不明白爲什麼這會得到downvoted –