他们有什么意义?
我从来没有把它们用于任何东西,我看不出自己需要使用它们。
我错过了关于他们的事情还是他们几乎没用?
编辑:我对它们了解不多,所以可能需要对它们进行描述......
答案 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 );