4

それらのポイントは何ですか?
私はそれらを何にも使用したことがなく、それらを使用する必要があるとはまったく思いません.
私はそれらについて何かを見逃していますか、それともほとんど役に立たないのですか?

編集:私はそれらについてあまり知らないので、それらについての説明が必要かもしれません...

4

3 に答える 3

10

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

使用されている PMFの例を次に示します (.*演算子が使用されている「魔法の」行に注意してください: (lhs.*opit->second)(...)、および PMF を作成するための構文&class::func):

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

ダウンロード

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

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

于 2009-04-14T07:30:30.313 に答える
4

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

これの用途の 1 つは「コールバック」です。バックグラウンド プロセスをしばらく動作させたいとします。完了したらお知らせください (GUI などを更新できるようにします)。しかし、このバックグラウンド プロセスで 1 つのメソッドを呼び出したい場合もあれば、別のメソッドを呼び出したい場合もあります。このバックグラウンド プロセスの 2 つのバージョンを記述するのではなく、バックグラウンド プロセスが「コールバック」する関数へのポインタを受け取るように記述できます。次に、プロセスが終了すると、最初に指定された関数を呼び出します。

基本的には、どのメソッドを呼び出すかを決定する際の柔軟性が大幅に向上するだけです。そういう意味では、ポリモーフィズムとよく似ています。実際、舞台裏では、C++ は関数へのポインターを使用してポリモーフィズムを促進していると思います (クラスごとに関数へのポインターの異なるテーブルを格納することにより)。

于 2009-04-14T07:08:35.497 に答える
1

あなたの質問を正しく理解できれば。なぜだめですか?

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

test tt;
boost::bind( &test::operator ->, _1 )( tt );
于 2009-04-14T07:29:30.597 に答える