天天看點

c++箭頭操作符(->)重載函數

  箭頭(->)操作符是個二進制操作符,其左操作數是類對象的位址或者是重載了箭頭運算符的類對象,右操作數是類的成員。箭頭操作符重載函數隻能是類的成員函數(參考為什麼有的操作符重載函數隻能是成員函數?)。

  箭頭運算符的使用方法為:

obj->mem;       
obj->func();
           

  obj為某個類對象的位址,mem和func()分别是該對象的成員變量和成員函數,這樣的用法是我們之前學習的。在引入操作符重載後,obj還可以是重載了->操作符的類對象(注意是對象而非位址),mem和func()依舊是類對象的成員,但是注意,它不再是obj對象的成員。

  對于上述代碼語句,編譯器是這樣處理的:

  步驟(1):倘若obj是指針(或者說位址),指向的是具有成員變量mem(成員函數func())的類對象,那麼obj->mem傳回成員變量mem,obj->func()調用成員函數func();

  步驟(2):倘若obj是一個重載了->操作符的類對象,那麼調用obj對象的operator->()函數,該函數的傳回值有兩種情況:①傳回指針,執行步驟(1);②傳回重載了->操作符的類對象,執行步驟(2),直至傳回的是指針。

  是以若obj是一個重載了->的類對象,那麼mem和func()将不是obj的成員,而是->運算符重載函數最終傳回的指針指向的對象的成員。

  用下面代碼加深了解:

  (1)左操作數是對象的指針

using namespace std;
struct A
{
    void func() { printf("A::func()\n"); }
};

int main(void)
{
    A *aobj = new A;
    aobj->func();       //簡單,列印A::func()

    return ;
}
           

  (2)左操作數是重載->操作符的類對象,該重載函數傳回的是某個對象的指針

struct C
{
    void func() { printf("C::func()\n"); }
};

struct B
{
    C m_c;
    C* operator->() { return &m_c; }
};

int main(void)
{  
    B bobj; //bobj是一個對象,但它重載了->操作符
    bobj->func();   //執行的是C::func(),即列印C::func()

    return ;
}
           

  (3)左操作數是重載->操作符的類對象,重載函數傳回的是另一個重載了->操作符的類的對象

struct F
{
    void func() { printf("F::func()\n"); }
};

struct E
{
    F m_f;
    F* operator->() { return &m_f; }    //傳回m_f對象的位址
};


struct D
{
    E m_e;
    E operator->() { return m_e; }  //傳回m_e對象,該對象重載了->操作符
};

int main(void)
{
    D d;
    d->func();  //等價于d.operator->().operator->()->func(),列印F::func()

    return ;
}
           

繼續閱讀