11

次のコードは、https ://github.com/facebook/folly/blob/master/folly/Synchronized.h から抽出されたものです。

最近、Folly ライブラリを調べたところ、興味深いものが見つかりました。次の例を検討してください。

#include <iostream>

struct Lock {
    void lock() {
        std::cout << "Locking" << std::endl;
    }
    void unlock() {
        std::cout << "Unlocking" << std::endl;
    }
};

template <class T, class Mutex = Lock >
struct Synchronized {
    struct LockedPtr {
        explicit LockedPtr(Synchronized* parent) : p(parent) {
            p->m.lock();
        }

        ~LockedPtr() {
            p->m.unlock();
        }

        T* operator->() {
            std::cout << "second" << std::endl;
            return &p->t;
        }

    private:
        Synchronized* p;
    };

    LockedPtr operator->() {
        std::cout << "first" << std::endl;
        return LockedPtr(this);
    }

private:
    T t;
    mutable Mutex m;
};

struct Foo {
    void a() {
        std::cout << "a" << std::endl;
    }
};

int main(int argc, const char *argv[])
{
    Synchronized<Foo> foo;
    foo->a();

    return 0;
}

出力は次のとおりです。

first
Locking
second
a
Unlocking

私の質問は: なぜこのコードは有効なのですか? このパターンに名前はありますか?

-> 演算子は 2 回呼び出されますが、1 回しか書かれていません。

4

2 に答える 2

12

それが標準が言っていることだからです:

13.5.6 クラスメンバーアクセス [over.ref]

1)operator->パラメータを取らない非静的メンバー関数でなければなりません。式は、存在する場合、およびオーバーロード解決メカニズム (13.3) によって最適一致関数として演算子が選択された場合、クラス オブジェクトとして解釈されます。-> postfix-expression -> id-expression x->m(x.operator->())->mxTT::operator->()

(私のものを強調)

あなたの場合、xisfoomis a()、今、Synchronizedoverloadsoperator->foo->a()次と同等です:

(foo.operator->())->a();

foo.operator->()はクラスのオーバーロードでSynchronizedあり、 a を返し、それが独自のLockedPtrを呼び出します。LockedPtroperator->

于 2012-09-11T08:17:07.073 に答える
0

これを自問してみてください。他にどのように動作する可能性がありますか?

オーバーロードのポイントはoperator->、スマートポインタクラスが生のポインタと同じ構文を使用できるようにすることです。つまり、次の場合です。

struct S
{
    T m;
};

pへのポインタがあり、がまたは何らかのタイプであるかどうかに関係なく、経由でSアクセスします。S::mp->mpS*pointer_class<S>

直接使用する->ことと呼び出すことには違いもあります。operator->

pointer_class<S> pointerObj;
S* p = pointerObj.operator->();

オーバーロードを使用して->も自動的に余分なレベルがp->m下がらない場合は、どういう意味になるのでしょうか。過負荷をどのように使用できますか?

于 2012-09-11T08:33:34.390 に答える