-3

歴史: オーバーロードできる理由 -> ではなく . オペレーター?どちらもメンバーアクセス演算子であり、同じ意味を持ちます。

私はいくつかの参照を読みました

http://www.stroustrup.com/bs_faq2.html#overload-dot

operator-> を手動でオーバーロードできるのはなぜですか?

しかし、-> ではなく .operator をオーバーロードできるのはなぜでしょうか?

-> 演算子が暗黙的に戻りポインターの参照を取得し、チェーン呼び出しとして呼び出しを行うためですか

struct X {
    int foo;
};

struct Y {
    X x;
    X* operator->() { return &x; }
};

struct Z {
    Y y;
    Y& operator->() { return y; }
};

Z z;
z->foo = 42;          // Works!  

z->foo = 42; この呼び出しは ((z.operator()).opeartor()).operator() に変換されるため、foo の値は 42 に設定されます。

質問:- この点を取ると、まだ 2 つの点があります。

1) .(ドット) 演算子がこのように機能しないのはなぜですか?

2) -> 演算子がクラス Y への参照を返さない場合はどうなりますか? その場合、コンパイルエラーになりますか?

4

1 に答える 1

4

これを読んだ後、 operator-> のオーバーロードがどのように機能するかを理解しただけです:

式 E1->E2 は、組み込み型の (*E1).E2 とまったく同じです。ユーザー定義の operator-> が提供されている場合、operator-> は、プレーン ポインターを返す operator-> に到達するまで、返された値に対して再帰的に呼び出されます。その後、組み込みのセマンティクスがそのポインターに適用されます。

2 番目の質問に答えるには、例をもう一度見てみましょう。

struct X { int foo; };

struct Y {
    X x;
    X* operator->() { return &x; } // returns pointer 
};

struct Z {
    Y y;
    Y& operator->() { return y; } // returns reference
};

Z z;
z->foo = 42;          // Works!

呼び出しz->は に評価されz.yます。これはポインターではないため、再帰が続行(z.y)->されます: に評価され&(z.y.x)ます。これはポインターであり、結果の式は(&(z.y.x))->です。

Zs 演算子にポインターを返すようにすると、再帰は で停止しますが、 a&(z.y)がなく、コンパイラーは文句を言います。Yfoo

于 2015-09-12T12:55:37.760 に答える