簡體   English   中英

為什么編譯器會兩次調用 - >運算符

[英]Why does the compiler invoke the -> operator twice

以下代碼摘自: 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

我的問題是:為什么這段代碼有效? 這個模式有名字嗎?

- >運算符被調用兩次,但它只寫了一次。

因為這就是標准所說的:

13.5.6類成員訪問[over.ref]

1) operator->應該是一個不帶參數的非靜態成員函數。 它使用-> postfix-expression -> id-expression實現類成員訪問如果T::operator->()表達式x->m被解釋為(x.operator->())->m表示類型為T的類對象x T::operator->()存在,如果操作符被重載決策機制選為最佳匹配函數(13.3)。

(強調我的)

在你的情況下, xfooma() ,現在, Synchronized重載operator->foo->a()相當於:

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

foo.operator->()是您在Synchronized類中的重載,它返回一個LockedPtr ,然后LockedPtr調用它自己的operator->

問問自己:它可能還有什么其他表現?

請記住,重載operator->的重點是智能指針類可以使用與原始指針相同的語法。 也就是說,如果你有:

struct S
{
    T m;
};

並且你有一個指針pS ,然后通過p->m訪問S::m ,無論pS*還是某個pointer_class<S>類型。

使用->和直接調用operator->之間也有區別:

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

請注意,如果使用重載->沒有自動降低額外級別,那么p->m可能意味着什么? 如何使用過載?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM