4

演算子のオーバーロードに関する書籍やスタック オーバーフローの記事を調べたところ、次のことがわかりました。

オーバーロードされた演算子がメンバー関数の場合、これは左側のオペランドにバインドされます。メンバー演算子関数には、オペランドの数よりも 1 つ少ない (明示的な) パラメーターがあります。

(Addison Wesley、C++ 入門)

したがって、私の質問は、*(逆参照) 演算子には左オペランドがないため、どのようにしてそのパラメーター (オブジェクト自体またはthis) を取得するのですか?

4

3 に答える 3

3

すべての前置単項演算子の場合、その後に続くオペランドに作用します。

追加の質問として、オーバーロードされた * 演算子が非メンバー関数として定義されている場合とメンバー関数として定義されている場合、演算子の使用方法に違いはありますか

非メンバー関数はそのクラスのプライベート メンバーにアクセスできず、メンバー関数と非メンバー関数の両方が存在する場合、コンパイラはオーバーロード解決を使用して上位の関数を選択する必要があることを除いて、ほとんどの場合、いいえ。 「より良い機能ではありません。あいまいな呼び出しです。ADL を参照してください。

信頼できるソースについては、operator overloading、または標準 C++ のセクション 13.5.1 [over.unary] を参照してください。

前置単項演算子は、パラメーターを持たない非静的メンバー関数 (9.3) または 1 つのパラメーターを持つ非メンバー関数によって実装されます。したがって、接頭辞単項演算子 @ の場合、@x は x.operator@() または operator@(x) として解釈できます。演算子関数の両方の形式が宣言されている場合、13.3.1.2 の規則によって、使用される解釈がある場合はどちらが使用されるかが決まります。後置単項演算子 ++ および -- の説明については、13.5.7 を参照してください。2 同じ演算子の単項および 2 項形式は、同じ名前を持つと見なされます。[ 注: したがって、単項演算子は、囲んでいるスコープから二項演算子を隠すことができ、その逆も可能です。—終わりのメモ]

会員と非会員の両方が存在する場合の選択については、13.3.1.2 [over.match.oper] を参照してください。

于 2016-11-02T01:42:00.663 に答える
0

Prefix*は、それに続くオペランドに作用します。

operator*メンバー関数として表現されたユーザー定義の場合、それはthis-expression によって参照されるオブジェクトです。

#include <iostream>
using namespace std;

struct S
{
    auto operator*() const -> char const* { return "Hi there!"; }
};

auto main()
    -> int
{ cout << *S() << endl; }

結果:

やあ!
于 2016-11-02T01:18:57.673 に答える
0

The dereference operator works exactly the same way as an overloaded operator as it does as an ordinary operator.

int foo(int *p)
{
     return *p;
}

In the statement return *p;, the dereference operator applies to the pointer p. It is passed to it on the right side:

As an overloaded operator, it works the same way.

class bar {

     int *some_internal_ptr;

public:
     int operator*() const {
          return *some_internal_ptr;
     }

     // Other class members and methods...
};

int foo(bar p)
{
     return *p;
}

When the right-hand side of the * operator is class with an operator*` member, it gets invoked as an overloaded method of the class, no different than any other member, in order to resolve the dereference.

It is because the usage is identical is why many C++ library algorithms work equally well with either pointers or C++ library operators. For example, std::copy() could be implemented as follows (I am trimming away some irrelevant complexity that's not germane here):

template<typename iter_type>
iter_type copy(iter_type b, iter_type e, iter_type t)
{
    while (b != e)
    {
       *t=*b;
       ++t;
       ++b;
    }
    return t;
}

You can pass native pointers to std::copy, or pass classes like iterators, with overloaded * operators, and because an overloaded * operator is used with the same syntax as an ordinary * operator, the same algorithm works with the overloaded operator as well.

于 2016-11-02T01:25:46.007 に答える