2012-05-04 59 views
1
#include <iostream> 
using namespace std; 

class B 
{ 
public: 
    int getMsg(int i) 
    { 
    return i + 1; 
    } 
}; 

class A 
{ 
    B b; 
public: 
    void run() 
    { 
    taunt(b.getMsg); 
    } 

    void taunt(int (*msg)(int)) 
    { 
    cout << (*msg)(1) << endl; 
    } 
}; 

int main() 
{ 
    A a; 
    a.run(); 
} 

上面的代碼在類A中有一個類B,而類A有一個將函數作爲參數的方法taunt。 B類的getMsg傳入嘲諷...上述代碼生成以下錯誤消息:「錯誤:沒有匹配函數調用'A :: taunt()'」C++:使用函數指針時的無法解析的重載函數

什麼導致上述代碼中的錯誤消息?我錯過了什麼嗎?

更新:

#include <iostream> 
using namespace std; 

class B 
{ 
public: 
    int getMsg(int i) 
    { 
    return i + 1; 
    } 
}; 

class A 
{ 
    B b; 
public: 
    void run() 
    { 
    taunt(b.getMsg); 
    } 

    void taunt(int (B::*msg)(int)) 
    { 
    cout << (*msg)(1) << endl; 
    } 
}; 

int main() 
{ 
    A a; 
    a.run(); 
} 

t.cpp:在構件函數 'void A ::運行()': 第19行:錯誤:調用沒有匹配的函數 'A ::嘲諷()'由於 - 重大錯誤,編譯終止了 。

改變(* MSG)(INT)後,我仍然得到同樣的錯誤(B :: * MSG)(INT)

+0

不能像C++那樣使用成員函數指針。嘗試使用谷歌搜索,有很多關於它的文章。 – mfontanini

+0

在一個地方,你傳遞一個'int',期望一個'int(*)(int)',另一個你傳遞一個'int(B :: *)(int)',其中一個int (*)(int)'是預期的;你爲什麼希望這個工作? – ildjarn

+0

我剛剛注意到了......我只是修復了它 – user52343

回答

2

b.getMsg不是形成一個指向成員的正確方法,你需要&B::getMsg

(*msg)(1)不是通過指向成員的指針調用函數的正確方法,您需要指定一個對象來調用該函數,例如, (使用臨時)(B().*msg)(1)

+1

+1,雖然你並不需要'&'。 –

+0

@SethCarnegie:'&'是必需的。 ISO/IEC 14882:2011 5.3.1/4:「只有在使用明確的&時纔會形成指向成員的指針,並且其操作數是不包含在圓括號中的_qualified-id_。 –

+0

啊,你說得對,謝謝你的糾正。如果我可以的話,我會再次給你+1) –

0

在OOP中做這樣的事情的正確方法是使用接口,所以你需要做的就是定義一個接口並在B類中實現它,然後將實現此接口的實例的指針傳遞給類中的方法A.

class IB{ 
public: 
virtual void doSomething()=0; 
}; 

class B: public IB{ 
public: 
virtual void doSomething(){...} 
}; 

class A{ 
public: 
void doSomethingWithB(IB* b){b->doSomething();} 
}; 
0

此工程於2010年VS輸出是所有線路上的相同:

#include <iostream> 
#include <memory> 
#include <functional> 

using namespace std; 
using namespace std::placeholders; 

class A 
{ 
public: 
    int foo(int a, float b) 
    { 
     return int(a*b); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    A temp; 

    int x = 5; 
    float y = 3.5; 

    auto a = std::mem_fn(&A::foo); 
    cout << a(&temp, x, y) << endl; 

    auto b = std::bind(a, &temp, x, y); 
    cout << b() << endl; 

    auto c = std::bind(std::mem_fn(&A::foo), &temp, _1, y); 
    cout << c(5) << endl; 
} 

基本上,你用std::mem_fn讓你調用對象的成員函數,然後std::bind如果你想綁定額外的參數,包括對象指針本身。如果你願意的話,我很確定有一種方法可以使用std::ref來封裝對象的引用。我還包含_1轉發標記,只是爲了指定綁定中的某些參數的另一種方法,而不是其他方法。你甚至可以指定所有的東西,但是類實例,如果你想要一樣的參數給所有東西,但它可以在不同的對象上工作。由你決定。

如果您更願意使用boost::bind它可以識別成員函數,並且您可以將它全部放在一行中稍微縮短一點:auto e = boost::bind(&A::foo, &temp, x, y)但顯然,使用完全的std C++ 11調用也不多。