2013-09-27 56 views
1

我有一組函數和一個函數指針,在我的頭文件中聲明如下。爲什麼這個函數指針失敗?

public:  // User declarations 
void __fastcall TTopForm::Method1(void); 
void __fastcall TTopForm::Method2(void); 
void __fastcall TTopForm::Method3(void); 
void __fastcall (TTopForm::*Method)(void) ; 

然後在我的節目,我做這個

Method = Method1; 

生成此錯誤消息:「成員函數必須被調用或採取其地址。」 所以當然我嘗試這個,但沒有運氣。

Method = &Method1; 

我在做什麼錯?我是一位電路設計師,而不是代碼專家,所以請給出一些明確的代碼。

感謝您的答案。我會發布我爲其他任何可能使用C++ Builder所做的工作。我在他們的幫助文件中使用了typedef。在typedef中省略__fastcall是我的錯誤之一。

class TTopForm : public TForm 
{ 
typedef void (__fastcall TTopForm::* TMethod)(void); 
... 

public:  // User declarations 
void __fastcall TTopForm::Method1(void); 
void __fastcall TTopForm::Method2(void); 
void __fastcall TTopForm::Method3(void); 
... 

然後在我的代碼:

TMethod Method = &TTopForm::Method1; 
(TopForm->*Method)(); 

回答

4

正確的語法是Method = &TTopForm::Method1;

類的成員函數是與正常自由函數不同的野獸。認爲它們完全不相關可能會更好。

您只能使用上面顯示的語法獲取地址。還有很多其他的東西你需要學會正確使用它們,例如,成員函數總是需要一個對象被調用。

+0

謝謝你,你的語法的作品,但現在()方法提供了一個「調用非功能」的錯誤。根據你的評論,我嘗試在函數的參數列表中添加TObject * Sender,但這沒有幫助。 –

+1

我看不到代碼,但在你的問題中'方法'是一個*指針*成員函數。您需要提供要調用它的對象。例如,假設你有一個類型爲「TTopForm」的對象't',你可以這樣調用它:'(t。* Method)();'。 –

1

你需要把它的地址是這樣的:

Method = &TTopForm::Method1; 
-1

我覺得

Method = Method1; 

應該是:

Method = ObjectOfClass.Method1 

我不知道但是。

+0

這確實是不對的。 – MSalters

1

傑西根據C++標準所期待的回答了這個問題。由於您專門使用C++ Builder,因此可以利用其編譯器擴展__closure,該擴展比標準C++方法指針更容易使用,並且更加靈活。例如:

class TTopForm : public TForm 
{ 
    typedef void __fastcall (__closure *TMethod)(void); 
    ... 

public:  // User declarations 
    void __fastcall Method1(void); 
    void __fastcall Method2(void); 
    void __fastcall Method3(void); 
    ... 
}; 

TMethod Method = &Method1; 
Method(); // calls this->Method1() 

是什麼讓__closure靈活的是,它不侷限於任何特定類別。它擁有對象指針的引用,所以它根本不需要知道原始類的類型。例如,下面的內容也是有效的:

typedef void __fastcall (__closure *TMethod)(void); 

class TTopForm : public TForm 
{ 
public:  // User declarations 
    void __fastcall Method1(void); 
    ... 
}; 

class TBottomForm : public TForm 
{ 
public:  // User declarations 
    void __fastcall Method1(void); 
    ... 
}; 

TTopForm *TopForm = ...; 
TBottomForm *BottomForm = ...; 
TMethod Method; 

Method = &(TopForm->Method1); 
Method(); // calls TopForm->Method1() 

Method = &(BottomForm->Method1); 
Method(); // now calls BottomForm->Method1(), using the same TMethod variable!