2010-07-26 162 views
2

我需要這樣的一個功能:傳遞類的非靜態函數指針作爲參數

class Class_A 
{ 
    ... 
    bool ShowVariableConstituents(CString (* ValueOutput)(double)); 
    ... 
} 

bool Class_A::ShowVariableConstituents(CString (* ValueOutput)(double)) 
{ 
    double dUncalculatedValue; 
    .... 

    if(ValueOutput ) 
    { 
     CString strValue = ValueOutput(dUncalculatedValue); 
    } 
    .... 
} 

下面是一個例子,我需要如何使用它:

class Class_B : Class_A 
{ 
    ... 
    int Calculate(); 
    CString ValueOutput(double dValue); 
    ... 
} 

CString Class_B::ValueOutput(double dValue) 
{ 
CString strValue; 
strValue.Format("%6.2f", (dValue/m_dAmount * 100)); 
return strValue; 
} 

int Class_B::Calculate() 
{ 
... 
ShowVariableConstituents(& Class_B::ValueOutput); 
... 
} 

我得到的錯誤:

Error 1 error C2664: ' Class_A::ShowVariableConstituents': conversion of Parameter 1 from 'CString (__thiscall Class_B::* )(double)' in 'CString (__cdecl *)(double)' not possible

你能幫我做是正確的?

問候 camelord

+0

的幾個問題:

template<typename UnaryOperator> bool Class_A::ShowVariableConstituents(UnaryOperator op) { double dUncalculatedValue; CString strValue = op(dUncalculatedValue); return true; // false ? } 

然後,你可以按如下方式使用它ShowVariableConstituents私人? 確實ShowVariableConstituents必須接受任何功能或只是Class_B的方法(可能繼承)? 確實ValueOutput必須是一個實例方法?它在示例中看起來不像這樣,但示例可能會簡化。 – 2010-07-26 12:09:12

+0

還有一個問題。在什麼情況下一個類你想打電話ValueOutput在ShowVariableConstituents。與ShowVariableConstituents被調用的可能相同,或者可能是其他的? – 2010-07-26 12:10:58

+0

我已經更新了我的回答與工作代碼來證明我說的是概念。請忽略特定於Qt的項目。這是我目前唯一的IDE。 – 2010-07-26 12:22:37

回答

2

爲了使人們有可能通過指針成員函數,你應該修改你的功能如下:

bool ShowVariableConstituents(CString (Class_A::* ValueOutput)(double)) 

但它不會幫助,因爲你想要的指針傳遞給Class_B::ValueOutputClass_A什麼也不知道約Class_B

你的選擇是讓你的函數模板:

int Class_B::Calculate() 
{ 
    ShowVariableConstituents(std::bind1st(std::mem_fun(&Class_B::ValueOutput), this)); 
    return 0; // put your code here 
} 
+0

這很酷! Thx爲模板提示。 – camelord 2010-07-26 12:22:17

+0

不錯!感謝您向我們展示這一點。 – 2010-07-26 12:34:46

0

我相信你正在尋找的答案是答案在這裏我的問題:

std::tr1::function and std::tr1::bind

adapt_integrate是你A::ShowVariableConstituentsintegrand是你ValueOutput。它不完全相同,但是你遇到的問題是非靜態類成員函數會隱式地將this引用傳遞給它所「駐留」的類對象。我相信__thiscall Class_B::*部分就是這樣。您需要將您想要調用的函數包裝在靜態成員函數中。

如果需要的話,我可以嘗試回答我的問題翻譯成你的情況的代碼,但我不認爲我有足夠的能力:)

0

請爲什麼指向非靜態成員閱讀了不被支持。 http://www.parashift.com/c++-faq-lite/pointers-to-members.html

如果您正在尋求建立類似封閉的東西,你可以通過周圍對象的成員函數和對象上修改狀態匿名方式通過此功能,您既可以通過「本」到每個函數(ISN永遠不可能),或者你可以使用函子。

一個函數是一個類,主要由一個運算符()組成。你會做什麼(我沒有測試過,EVER)是用純虛擬運算符()創建一個基類。在您的派生類中,您可以在派生類中創建一個指針,以指向您希望修改其狀態的對象。你也會在派生類中實現一個虛擬操作符()。

在您要修改其狀態的類內部,創建此派生類(必須是朋友)的實例。你用你希望修改的類的「this」指針實例化這個派生對象。

所以當你想在你的代碼中傳遞這個函子時,你可以傳遞state_modified_class.derived_functor_class而不是指向state_modified_class成員函數的指針。您的函數showvariableconstituents將採用base_functor_class的參數而不是函數指針。

正如我所說,這是所有的理論。我不知道它是否會真正起作用。我不是C++專家。

編輯:

#include <QtCore/QCoreApplication> 
#include <iostream>; 
using namespace std; 

class BaseFunctor 
{ 
public: 
    virtual void operator()() = 0; 
}; 

class StateMod 
{ 
    friend class DerivedFunctor; 

public: 

    class DerivedFunctor : public BaseFunctor 
    { 

    public: 

     DerivedFunctor(StateMod * tempths) 
     { 
      ths = tempths; 
     } 

     virtual void operator()() 
     { 
      ths->temp++; 
     } 

    private: 
     StateMod * ths; 
    }; 

    DerivedFunctor derived; 


    StateMod(int x = 0) : derived(this) 
    { 
     this->temp = x; 
    } 

    void printTemp() 
    { 
     cout << "temp: " << temp << endl; 
    } 

    private: 
    int temp; 
}; 


class demonstration 
{ 
public: 

    void doit(BaseFunctor & basefunct) 
    { 
     basefunct(); 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    StateMod moddy; 
    demonstration demo; 


    moddy.printTemp(); 

    demo.doit(moddy.derived); 

    moddy.printTemp(); 

    return a.exec(); 
} 
+0

哦,不!我只是希望能夠讓ShowVariableConstituents(..)的調用者處理計算出的double值的輸出。我還可以做些什麼? – camelord 2010-07-26 12:07:19

0

您可以將指針到法不發送給一個函數/方法接收一個指針到一個無功能。

想一想,一個方法需要一個指向在其上應用的對象(this)。

編輯:

在你的情況,如果A :: ShowVariableConstituents的所有客戶實際上是從A(如B一樣)得到比你可能有一個虛方法CString A::ValueOutput(double)這將在派生類中overrided並呼籲來自A :: ShowVariableConstituents()。

順便說一句,這將是模板方法設計圖案的一個實例。

+0

這適用於我的情況,但模板提示更加通用。 – camelord 2010-07-26 12:23:52