3

私はオーバーロード ->* 演算子のこの特定の例を経験していました。なぜ () 演算子をオーバーロードする必要があるのか​​を理解しようと懸命に努力しましたが、多くのグーグル検索と再確認の後でそれを取得できませんでした。 operator ->* の戻り値。この ->* 演算子で必要なのは、クラスのスマート ポインターのように動作することであり、通常のポインターと同じようにメンバー関数を参照できる必要があることがわかりました。したがって、 (w->* pmf)(1) のように行います。ここで、->* は () の int の戻り値について知る必要があると思います。そのため、->* 演算子の上にオーバーロードされています。 . ネストされたイテレータの場合に私が持っていたもう1つの疑問は、ネストされたイテレータのようにするために -> のオーバーロードを行っているときに、ネストされたクラスをフレンドとして宣言する前に宣言する必要があるのはなぜですか? 私は C++ の初心者です。そのため、これらの質問は、申し訳ありませんが素朴すぎるように見えるかもしれませんが、これまで -> および ->* のオーバーロードに苦労してきたため、このことについて非常に深い知識が必要です。 .

#include <iostream>
using namespace std;
class Dog {
    public:
    int run(int i) const {
        cout << "run\n";
        return i;
    }
    int eat(int i) const {
        cout << "eat\n";
        return i;
    }
    int sleep(int i) const {
        cout << "ZZZ\n";
        return i;
    }
    typedef int (Dog::*PMF)(int) const;
    // operator->* must return an object
    // that has an operator():
    class FunctionObject {
        Dog* ptr;
        PMF pmem;
        public:
        // Save the object pointer and member pointer
        FunctionObject(Dog* wp, PMF pmf): ptr(wp), pmem(pmf) {
            cout << "FunctionObject constructor\n";
        }
        // Make the call using the object pointer
        // and member pointer
        int operator()(int i) const {
            cout << "FunctionObject::operator()\n";
            return (ptr->*pmem)(i); // Make the call
        }
    };
    FunctionObject operator->*(PMF pmf) {
        cout << "operator->*" << endl;
        return FunctionObject(this, pmf);
    }
};
int main() {
    Dog w;
    Dog::PMF pmf = &Dog::run;
    cout << (w->*pmf)(1) << endl;
    pmf = &Dog::sleep;
    cout << (w->*pmf)(2) << endl;
    pmf = &Dog::eat;
    cout << (w->*pmf)(3) << endl;
}
4

0 に答える 0