2009-04-14 7 views
4

どのような点がありますか?
私は決してそれらを何のためにも使用したことはありません。私はそれらをまったく使用する必要はありません。
私はそれらについて何か不足していますか、それともかなり役に立たないのですか?

編集:私はそれらについての説明が必要になることがあり、それらについて多くを知らない...C++のメンバー演算子へのバインドポインタ

+0

あなたが探しているのは、http://stackoverflow.com/questions/654853/why-would-one-use-function-pointers-to-member-method-in-cですか? – nevets1219

+0

いいえ、具体的には、*演算子と - > *演算子です。 – DeadHead

+0

私は彼がメンバーオペレーター(例:オペレーター+)へのポインタについて話していると思います。 –

答えて

10

A PMF(メンバ関数へのポインタ)を除いて、通常(静的)関数ポインタのようなものである、非静的メンバ関数を指定するthisオブジェクトを必要とするため、PMFの呼び出し構文(.*又は->*thisオブジェクトを指定できます(左側)。

(ここで使用されて.*オペレータと "魔法" の行に注意:(lhs.*opit->second)(...)、およびPMF、&class::funcを作成するための構文):使用中のPMFの例です

#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); 
     } 
    } 
} 

[Download]

実数ではなく複素数を使用する単純なRPN計算機です(ほとんどの場合、std::complexは演算子がオーバーロードされたクラス型です)。私はこれをclangでテストしました。あなたの走行距離は他のプラットフォームによって異なる場合があります。

入力は(0,1)の形式である必要があります。スペースはオプションですが、読みやすくするために追加することもできます。

+0

コードに_no_エラーチェックがありますが、とにかくそのアイデアを得ることを願っています。 :-D –

+0

ええ、意味があります。この例をありがとう。 – DeadHead

+0

空のスタック上でsegfaultsを取得すると実際に私に迷惑をかけるため、実際にエラーチェックを追加するように私のバージョンを更新しました。 :-) –

4

バインド関数へのポインタは、さまざまな状況で非常に便利です。基本的には、関数を変数として参照できるため、実行時に呼び出す関数を選択することができます。

「コールバック」には1つの用途があります。私はしばらくの間、いくつかのバックグラウンドプロセスを働かせて、それが完了したら私たちに知らせてください(GUIを更新するなど)。しかし、時には、このバックグラウンドプロセスが1つのメソッドを呼び出すことが必要な場合があります。また、別のメソッドを呼び出すこともあります。このバックグラウンドプロセスの2つのバージョンを書くのではなく、バックグラウンドプロセスが "コールバック"したい機能へのポインタを受け取るように書くことができます。その後、プロセスが終了すると、最初に与えられた機能のいずれかが呼び出されます。

基本的に、コールするメソッドを決定する際のヒープの柔軟性が向上します。そのようにして、それは多型に非常に似ています。実際には、私はC++が多型を容易にするための関数へのポインタを使用すると信じています(各クラスの関数へのポインタの別のテーブルを格納することにより)

1

私はあなたの質問を正しく理解しています。何故なの?

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

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

私の質問は、これらの演算子が何であるか、演算子を使用する代わりになるものほどではありません。 – DeadHead