2017-07-24 64 views
1

下面顯示的是一個工作代碼。但我想使用「this」關鍵字在我的實現中調用我的函數指針(例如在構造函數實現中)。請幫我想出一個解決方案。使用此關鍵字訪問C++中的函數指針

我的系統是 G ++(GCC)4.1.2 20080704(紅帽4.1.2-55)

工作守則

#include <iostream> 
#include <string> 
#include <map> 

using namespace std; 

class TestClass{ 
public: 
    typedef int (TestClass::*FunctionPtr)(int); 
    map <string, FunctionPtr> mFnPtrMap; 

    int Function1(int nAdd) { return nAdd + 1; } 
    int Function2(int nAdd) { return nAdd + 2; } 

    TestClass() { 
     mFnPtrMap.insert(make_pair("Function1", &TestClass::Function1)); 
     mFnPtrMap.insert(make_pair("Function2", &TestClass::Function2)); 
    } 

    int CallFunction(const string & s, int n) { 
     FunctionPtr fp = mFnPtrMap[s]; 
     return (this->*fp)(n); 
    } 
}; 

int main() { 
    TestClass ts; 
    cout << ts.CallFunction("Function1", 0) << endl; 
    cout << ts.CallFunction("Function2", 0) << endl; 
} 

我想要做的是:

我的期望是把它改成這樣的東西(用'this->'代替'TestClass ::')

mFnPtrMap.insert(make_pair("Function1", &this->Function1)); 

它給我一個編譯器錯誤。它甚至建議我使用TestClass :: name解析。

「ISO C++不允許取綁定的成員函數的地址,形成 一個成員函數指針。說&的TestClass ::功能1」

這是否意味着這是不可能的?如果有人可以給我一個解釋,這將有助於我理解下面的理論。謝謝。

+0

你爲什麼要改用類名的呢?你看到了什麼優勢? – HeroicKatora

+0

如果只是爲了避免顯式使用類名,我建議使用'decltype'和'std :: remove_pointer'來從'this'重建它。和C++ 11一樣,你可以使用下面這段代碼:std :: remove_pointer :: type'作爲顯式類名的直接替換 – HeroicKatora

+0

這不是獲得優勢。我想在代碼中給它一個非靜態的外觀,以適應我們所遵循的本地編碼標準。 – SajithP

回答

1

如果我不得不猜測C++標準的這部分背後的原因,那就是表達式的類型幾乎是等價的。只是相比較,你會如何需要調用的函數,如果在一個表達式沒有函數調用的某種間接的:

(this->*TestClass::function)(); // Binding the member pointer to an instance 

在這裏,我們的成員指針綁定到一個實例與->*運營商填補隱含T*每個成員函數都有一個名爲this的參數。有些其他語言要求你明確地提供它,例如Python,但我有點偏側。

this->function(); 

這裏的子表達式this->function已經綁定的this參數到本地this對象,它意味着這樣做其實絕不是指一個功能。因此,你不能接受它的地址。

你可能會認爲這應該被允許作爲標準的一部分,但考慮一個事實,即你可以在子類中隱藏函數聲明。這意味着引入表達&TestClass::function的第二個表達式只會引入混淆。在目前的形式中,我們非常清楚哪個function是我們所指的,而在this->function表單中它不會,尤其是新手可能會認爲這是完全動態的,因爲this不是靜態對象。假設實際上在表達之間存在差異也不是不合理的。

在平均時間,我只能提供一種通過某種類型的水平計算,除去明確的轉診到類:

#include <type_traits> 
template<typename T> 
using This = typename std::remove_const<typename std::remove_pointer<T>::type>::type; 

TestClass::TestClass() { 
    mFnPtrMap.insert(make_pair("Function1", &This<decltype(this)>::Function1)); 
    mFnPtrMap.insert(make_pair("Function2", &This<decltype(this)>::Function2)); 
} 
+0

僅受C++ 11支持。無論如何+1爲你的努力和解釋。 – SajithP

+0

@SajithP對不起,我沒有找到一種不使用C++ 11特性'decltype'的方法。 – HeroicKatora