簡體   English   中英

將類的成員函數傳遞給類外的參數

[英]Passing a member function of a class to a parameter outside the class

如何將一個類的成員函數作為參數傳遞給另一個類的另一個成員函數?

class theSecondClass
{
    public:
    void theFunctionReceiver(void (theFirstClass::*Function)(void));
    {
         // This part is wrong. "Operand of * must be a pointer"
         (*Function)(); 
    }
}

class theFirstClass
{
    public:
    theSecondClass * SecondClassInstance;
    void theFunctiontoPass(void)
    {
        printf("It worked \n");
        return;
    }
    void theFunctiontoCall(void)
    {
        SecondClassInstance->theFunctionReceiver(theFunctiontoPass);
    }
};

采取這一假設theSecondClasstheFirstClass都做出了。 我從某個地方調用theFirstClass->theFunctiontoCall()

我不明白 當我傳遞它時,它不是作為指針傳遞嗎?

我看過一些類似的主題,但是我不太了解它們。 我正在使用VS 2013基本編譯器。

當您編寫此語句時:

SecondClassInstance->theFunctionReceiver(theFunctiontoPass);

您大概的意思是:

SecondClassInstance->theFunctionReceiver(&theFunctiontoPass);

哪個應該給您一個編譯器警告,它是一個不合格的成員引用,它會向您指出您實際編寫的是:

SecondClassInstance->theFunctionReceiver(&theFirstClass::theFunctiontoPass);

您將獲得指向類定義上的成員函數的指針。 “ this”不是隱式的,也不包含在包中。 沒有類實例就可以調用它的唯一方法是它是靜態的。 (在這種情況下,它不會作為成員函數進行類型檢查,而只是普通的函數指針。)

如果要傳遞對類的引用,為什么還要傳遞該函數呢? 對於鏈接,我是否只能使用ButtonObj-> Buttonfunc()來調用它;

您使用指向成員函數的指針的唯一原因是要獲得某種抽象,其中一段代碼可以調用不需要顯式命名的成員函數。 如果您能夠接受theSecondClass::theFunctionReceiver知道的名字theFirstClass::theFunctionToPass和身份theFirstClass ......那么肯定,只是傳遞給theFirstClass的實例的引用,並明確調用該方法。

可能想要一種情況,即theSecondClass將調用具有匹配簽名的theFirstClass上的多個成員函數中的任何一個……它只是不想硬編碼哪個。 在那種情況下,然后可以傳遞一對類引用和一個成員函數。 您似乎懷疑這不會經常有用,您是正確的。 每年我都必須回過頭來查找有關如何在類上調用指向成員的指針的語法,因為除StackOverflow問題外,幾乎永遠不會出現這種語法:

如何通過成員函數指針調用?

您可能想要的(以及問那些SO問題的人實際上想要的)是將關注點分開,這樣, theSecondClass可以執行某些事情 ,但是根本不需要了解theFirstClass 查看lambdasstd :: functionstd :: bind以獲得通用的解決方案,您可以嘗試使用這些解決方案使您滿意。

這是一個示例,向您展示將調用抽象化為std :: function時的樣子。 它當場制作一個函數對象,捕獲this指針的包圍,以便在調用this指針時調用該對象上的方法:

#include <iostream>
#include <functional>

class theSecondClass {
public:
    void theFunctionReceiver(std::function<void()> const & Function) {
         Function(); 
    }
};

class theFirstClass {
private:
    theSecondClass * SecondClassInstance;
public:
    void theFunctiontoPass() {
        std::cout << "It worked\n";
    }
    void theFirstClass::theFunctiontoCall() {
        SecondClassInstance->theFunctionReceiver(
            [this]() {theFunctiontoPass();}
        );
    }
};

int main() {
    theFirstClass tfc;
    tfc.theFunctiontoCall();
}

請注意,這是C ++ 11,如果您尚未使用,我建議您使用。 但是,C ++ 98中存在不太方便的表示法和機制。

這可以糾正您代碼中超出您提到的問題的問題。 請查看編寫最小,完整,可驗證的示例 應該可以將提供的代碼粘貼到編譯器中,並且看到您要討論的錯誤。

  • 這將在類定義結束后添加分號
  • 當您在類中提供主體時,這將在方法聲明后刪除分號
  • 您需要各種前向定義才能使其按需運行,這不需要它們
  • 當函數不帶參數時,習慣上將其定義為void foo()而不是void foo(void) return; 因為函數的最后一行不返回任何值也是多余的。
  • 避免使用printf編寫新的C ++代碼, 學習iostreams
  • 將成員變量偏置為私有或受保護。
  • 在StackOverflow代碼示例上,請盡量使其簡短,並且不需要滾動條; 最好不要在大多數情況下給開括號使用自己的行

盡管命名是主觀的,但我建議給您的類名起一個大寫字母比給變量起一個大寫字母更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM