2017-07-24 39 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