運算符->的重載比較特別,它只能是非靜態的成員函數形式,而且沒有參數。
1、如果返回值是一個原始指針,那么就將運算符的右操作數當作這個原始指針所指向類型的成員進行訪問;
2、如果返回值是另一個類型的實例,那么就繼續調用這個返回類型的operator->(),直到有一個調用返回一個原始指針為止,然后按第一種情況處理。
如果上述條件不滿足(如:右操作數不是返回的原始指針指向的類型中的成員,或者,返回的非指針類型(另一個類型的實例)沒有重載operator->()),那么編譯將報錯。
以下是用於驗證的程序片段:
/******************************************************* * File Name:main.cpp * Description:演示成員訪問操作符->的重載 * Version:V1.0 * Author:Mengjia * Date:2018-05-20 * Copyright (C)2018, Mengjia * Others: ****************************************************************************** 運算符->的重載比較特別,它只能是非靜態的成員函數形式(即不能在類外重載), 而且沒有參數。 1、如果返回值是一個原始指針,那么就將運算符的右操作數當作這個原始 指針所指向類型的成員進行訪問; 2、如果返回值是另一個類型的實例,那么就繼續調用這個返回類型的operator->(),直到 有一個調用返回一個原始指針為止,然后就按第一種情況處理。 如果上述條件不滿足(如:右操作數不是返回的原始指針指向的類型的成員,或者, 返回的另一個類型的實例中沒有重載operator->()),那么編譯將報錯。 ****************************************************************************** *******************************************************/ #include <iostream> using namespace std; //原始類 struct Origin { int a; }; //包裝器類1,包裝Origin類 struct Wrapper { Origin* orig; Origin* operator->() const { return orig; //返回原始指針 } }; //包裝器類2,包裝Wrapper類 struct Wrapper2 { Wrapper* wrap; Wrapper& operator->() const { return *wrap; //返回類對象 } }; int main() { Origin o; o.a = 7; Wrapper w; w.orig = &o; Wrapper2 w2; w2.wrap = &w; cout << "w->a" << "\t\t\t\t" << w->a << endl; cout << "w.operator->()" << "\t\t\t" << w.operator->() << endl; cout << "w.operator->()->a" << "\t\t" << w.operator->()->a << endl; cout << "w2->a" << "\t\t\t\t" << w2->a << endl; cout << "&w2.operator->()" << "\t\t" << &w2.operator->() << endl; cout << "w2.operator->()->a" << "\t\t" << w2.operator->()->a << endl; cout << "w2.operator->().operator->()" << "\t" << w2.operator->().operator->() << endl; cout << "w2.operator->().operator->()->a" << "\t" << w2.operator->().operator->()->a << endl; system("pause"); return 0; } /* *輸出結果: w->a 7 w.operator->() 00AFF7E4 w.operator->()->a 7 w2->a 7 &w2.operator->() 00AFF7D8 w2.operator->()->a 7 w2.operator->().operator->() 00AFF7E4 w2.operator->().operator->()->a 7 **/
其中,最為詭異的就是w2->a輸出的是7。
按照上面總結的結論,這個調用其實會被編譯器轉換成w2.operator->().operator->()->a的形式,所以輸出的是7。