結構解引用運算符(Structure dereference operator),也稱通過指針訪問成員運算符(Element selection through pointer),是 C語言與C++的運算符。其功能是獲取運算符左側的指針所指向的對象的某個成員。該運算符的優先權較高,與函式調用運算符、數組下標運算符、通過引用選擇成員運算符相同,也是自左向右結合。
基本介紹
- 中文名:結構解引用運算符
- 外文名:Structure dereference operator
- 學科:計算機語言
- 功能:指向左側對象的某個成員
- 別名:通過指針訪問成員運算符
- 有關術語:運算符
定義,運算符重載,優先權別和結合性,代碼示例,
定義
結構解引用運算符是一個雙目運算符,獲取->所指單元的內容。當某個類中對->操作符重載時,是將該類對象當做一個指針看待,而用->操作符提取指針所指向的內容。結構解引用運算符必須是類的成員函式。結構解引用運算符的返回值必須是一個指針,或者是一個重載了結構解引用運算符的對象。如果返回的是一個指針將調用內置的結構解引用運算符、如果返回是一個重載了如果返回是一個重載了箭頭運算符的對象,則繼續對該對象調用其重載了的箭頭運算符,直到返回的是一個指針的對象,則繼續對該對象調用其重載了的結構解引用運算符,直到返回的是一個指針。該運算符可以視作為解引用運算符*的語法糖。即p->a相當於(*p).a。C++對該運算符的使用規定為:
運算符左端如果是個指針類型,則直接對該指針類型解引用訪問所指向對象的成員。即該運算符重載在此情形下未被使用。
運算符左端如果不是指針類型,編譯器則調用該運算符的重載版本。如果沒有重載版本則編譯報錯。該運算符的重載版本的返回值,或者是指針類型,或者是內含重載定義了->運算符的類型;對這兩種情形編譯器分別做指針解引用與遞歸調用返回類型的重載版本的->運算符。
運算符重載
運算符用於執行程式代碼運算,會針對一個以上運算元項目來進行運算。運算符重載是賦予運算符多重含義。通過重新定義運算符,使它能夠用於特定類的對象執行特定的功能。運算符重載是針對新類型數據的實際需要,對原有運算符進行適當改造。一般來講,重載的功能應當與原有功能相類似,不能改變原運算符的操作對象個數,同時至少有一個操作對象是自定義的類型。運算符重載是函式重載的一種特殊套用。
所謂函式重載簡單地說就是賦給同一個函式名多個含義。具體地講,C+ +中允許在相同的作用域內以相同的名字定義幾個不同實現的函式,可以是成員函式,也可以是非成員函式。但是,定義這種重載函式時要求函式的參數或者至少有一個類型不同或者個數不同。C+ +把運算符視為特殊的函式,因此運算符重載就是函式重載的一種特殊情況。像對待一般重載函式一樣,編譯系統能夠依據調用運算符的不同環境,即參數(運算元)的數量或類型的差異,區分同一運算符的不同含義。除了new和delete這2個較為特殊運算符以外,任何運算符如果作為成員函式重載必須是非靜態成員函式,其第一運算元就是該對象本身,因此不出在參數表中出現(或者說第一運算元是通過隱含的this指針傳遞的):如果作為非成員函式重載,所有的運算元都應作為參數在參數表中出現,因此參數表中至少有一個參數。大部分運算符既可以作為成員函式重載,又可以作為非成員函式重載,但= ,[],(),和->這4個運算符只能作為成員函式進行重載,而且不能是針對枚舉型運算元的重載。
優先權別和結合性
C語言將這34種運算符規定了不同的優先權別和結合性。優先權是用來標識運算符在表達式中的運算順序的,在求解表達式的值的時候,總是先按運算符的優先次序由高到低進行操作,可是,當一個運算對象兩側的運算符優先權別相同時,則按運算符的結合性來確定表達式的運算順序。
運算符的結合性指同一優先權的運算符在表達式中操作的組織方向,即:當一個運算對象兩側運算符的優先權別相同時,運算對象與運算符的結合順序,C語言規定了各種運算符的結合方向( 結合性) 。大多數運算符結合方向是“自左至右”,即:先左後右,例a- b+c,b兩側有- 和+兩種運算符的優先權相同,按先左後右結合方向,b先與減號結合,執行a- b的運算,再執行加 c 的運算。除了自左至右的結合性外,C語言有三類運算符參與運算的結合方向是從右至左。即:單目運算符,條件運算符,以及賦值運算符。關於結合性的概念在其他高級語言中是沒有的,這是 C語言的特點之一, 特別是從右至左結合性容易出錯。
在數學和計算機科學中,運算次序(也稱為運算順序、運運算元優先權)是指決定在表示式中的哪一運運算元首先被執行的規則。比如,在四則運算中,一般有先乘除後加減的規定。就是說在2 + 3×4這樣的式子中,按規定會先對3和4作乘法,得出12,然後再把2和12加起來,最後就得出14。
代碼示例
#include <iostream> class foo{public: void func(){ std::cout<<"foo say hello "<<std::endl; }};class bar{ foo a;public: foo* operator->(){ return &a; } void func(){ std::cout<<"bar said hello"<<std::endl; }};class D{ bar b;public: bar operator->(){ return b; } void func(){ std::cout<<"D said hello"<<std::endl; }};int main(){ D dumb, *pd=&dumb; pd->func(); //pc為一個類的指針 所以直接解引用 D d; d->func(); //d不是一個指針類型,所以調用了D::operator->()重載版本}