在C ++中绑定指向成员运算符的指针

时间:2009-04-14 06:57:54

标签: c++ operators

他们有什么意义?
我从来没有把它们用于任何东西,我看不出自己需要使用它们。
我错过了关于他们的事情还是他们几乎没用?

编辑:我对它们了解不多,所以可能需要对它们进行描述......

3 个答案:

答案 0 :(得分:10)

PMF(指向成员函数的指针)就像普通(静态)函数指针一样,除非因为非静态成员函数需要指定this对象,所以PMF调用语法({{1} }或.*)允许指定->*对象(在左侧)。

以下是正在使用的PMF的示例(请注意使用this运算符的“魔术”行:.*以及创建PMF的语法(lhs.*opit->second)(...)):< / p>

&class::func

[Download]

这是一个简单的RPN计算器,使用复数而不是实数(主要是因为#include <complex> #include <iostream> #include <map> #include <stack> #include <stdexcept> #include <string> namespace { using std::cin; using std::complex; using std::cout; using std::invalid_argument; using std::map; using std::stack; using std::string; using std::underflow_error; typedef complex<double> complexd; typedef complexd& (complexd::*complexd_pmf)(complexd const&); typedef map<char, complexd_pmf> opmap; template <typename T> typename T::reference top(T& st) { if (st.empty()) throw underflow_error("Empty stack"); return st.top(); } } int main() { opmap const ops{{'+', &complexd::operator+=}, {'-', &complexd::operator-=}, {'*', &complexd::operator*=}, {'/', &complexd::operator/=}}; char op; complexd val; stack<complexd> st; while (cin >> op) { opmap::const_iterator opit(ops.find(op)); if (opit != ops.end()) { complexd rhs(top(st)); st.pop(); // For example of ->* syntax: complexd& lhs(top(st)); // complexd* lhs(&top(st)); (lhs.*opit->second)(rhs); // (lhs->*opit->second)(rhs); cout << lhs << '\n'; // cout << *lhs << '\n'; } else if (cin.unget() && cin >> val) { st.push(val); } else { throw invalid_argument(string("Unknown operator ") += op); } } } 是一个带有重载运算符的类类型)。我用clang对此进行了测试;您的里程可能因其他平台而异。

输入的格式应为std::complex。空格是可选的,但可以添加以便于阅读。

答案 1 :(得分:4)

将指针绑定到某个函数在各种情况下非常有用。基本上,它允许您将函数称为变量,这使您可以在运行时选择要调用的函数。

一个用途就是“回调”。假设我想要一些后台进程工作一段时间,让我们知道它什么时候完成(所以我们可以更新GUI,或者其他东西)。但有时候,我们可能希望这个后台进程调用一个方法,有时候,我们希望它调用另一个方法。我们可以编写它,而不是编写这个后台进程的两个版本,以便后台进程接收指向我们希望它“回调”的函数的指针。然后,当过程结束时,它会调用它首先给出的任何函数。

基本上,它只是让你在决定调用哪个方法时有更大的灵活性。这样,它与多态性非常相似。事实上,在幕后,我相信C ++使用指向函数的指针来促进多态(通过为每个类存储不同函数的指针表)

答案 2 :(得分:1)

如果我理解你的问题。为什么不呢?

struct test
{
    test* operator->() 
    { 
        std::cout << "test::operator->";
        return this; 
    }
};

test tt;
boost::bind( &test::operator ->, _1 )( tt );