2017-02-22 100 views
8

我無法在從void*投下的對象上調用指向成員函數的指針。見下面的例子:無法通過靜態方法調用指向成員函數的指針

class Test 
{ 
public: 
    Test(int pointTo) 
    { 
     if (pointTo == 1) 
      function = &Test::Function1; 
     else 
      function = &Test::Function2; 
    } 

    static void CallIt(void* cStyle) 
    { 
     Test* t(static_cast<Test*>(cStyle)); 
     (t->*function)();// error C2568: '->*': unable to resolve function overload 
    } 

    void CallIt() 
    { 
     (this->*function)();// Works just fine 
    } 

private: 
    typedef void (Test::*ptrToMemberFunc)(); 

    ptrToMemberFunc function; 

    void Function1() 
    { 
     std::cout << "Function 1" << std::endl; 
    } 

    void Function2() 
    { 
     std::cout << "Function 2" << std::endl; 
    } 
}; 

int main() 
{ 
    Test t1(1); 
    Test t2(2); 

    Test::CallIt(static_cast<void*>(&t1)); 
    Test::CallIt(static_cast<void*>(&t2)); 

    t1.CallIt(); 
    t2.CallIt(); 

    return 0; 
} 

當對象被轉換爲void*和後面會發生什麼?爲什麼我不能再調用指向成員函數的指針?

編輯:

修改CallIt()如下允許程序編譯,但我仍然好奇,爲什麼原來沒有工作。

static void CallIt(void* cStyle) 
{ 
    Test* t(static_cast<Test*>(cStyle)); 
    Test::ptrToMemberFunc pf(t->function); 
    (t->*pf)(); 
} 
+0

這很有趣,我只是寫完全相同的代碼wandbox,下降到identificatiors。 Tuple_cat的回答解釋了這一點。基本上你必須鏈接對象和可調用,所以一個間接運算符是不夠的。一些編譯器給出了更易於理解的錯誤消息,就像他們告訴你,你可以這樣調用一個靜態成員 - 暗示你沒有這個指針 – Swift

+0

關於你的編輯,我只是​​認爲運算符' > *'扔掉你。考慮它只是一個名爲'call_with_this'的常規函數​​,它需要一個指向對象和成員函數的指針。那麼你最初的不工作呼叫是'call_with_this(t,function);'。這裏恰好如此,名稱'function'是'Test'類的非靜態成員,但它與't'無關。因爲你在一個靜態函數中,所以沒有'this'來查找名字'function'。一旦你要求't-> function',你就有一個具有可訪問名稱的實際值。 – GManNickG

+0

@GManNickG就是這樣。現在我看到了解決方案,我明白了,但我沒有意識到' - > *'操作符實際上正在做什麼(我正在將它讀作'(t - >(* function))')。 – Kerry

回答

10
main.cpp:17:14: error: invalid use of member 'function' in static member function 
     (t->*function)();// error C2568: '->*': unable to resolve function overload 
      ^~~~~~~~ 

function是一個非靜態數據成員,所以你不能從一個靜態函數訪問它。

如果你想引用tfunction,你可以做到這一點,像這樣:

 (t->*(t->function))(); 
+0

這就是爲什麼他被迫在非靜態成員中編寫'(this - > * function)()'的原因,最內層的間接運算符「獲取」了指針的值,而最外層允許在引用該對象時調用 – Swift

相關問題