c++中的型別查詢過程相對簡單,基本上就是名字查詢,這裡不再介紹。
對於 .cpp 檔案中呼叫的乙個函式 ( 成員函式 ), 編譯器主要做了下面三件事情 :
1 名字查詢 . 先在所在編譯單元中可見名字實體中進行名字查詢 .(1) 類成員函式優先
( 物件所在的類
->
基類).
一經找到就停止查詢
.如果沒有
,(2)
在相應的名字空間中做進一步的搜尋
; 如果還沒有
, 會根據
(3)
函式引數所在的名字空間中查詢
(keoning
查詢).
2 過載決議 . 根據所找到的名字進行過載決議 , 根據引數最匹配原則選擇相應的函式 .
3 可訪問性檢查 . 用以確定被選中的函式是否可以被呼叫 .
說明 :
1) 根據第一條 , 顯然 , 如果型別想和非成員函式一起工作 , 那麼它們應該放在同乙個名字空間中 . 比如 , 一般型別的過載運算子和引數型別放在同乙個標頭檔案中 / 或者同乙個名字空間下 .
2) 函式特化模板不參與過載決議 , 因此 , 如果想運用某個函式的特化 , 最好的方法是過載該函式 , 在實現中採用該特化來工作 .
3) 過載決議發生的可訪問性檢查之前 . 正因如此 , 如果私有函式不幸參與了過載 , 並且被選中的話 , 最終也會出現無法訪問的編譯提示 . 這常常隱含二義性 , 這樣設計也不合理 . 換句話說 , 私有引數 , 在名字查詢和過載時並非是 」 私有的 」.
以 c.twice ( 21 )的函式呼叫為例:
a) 名字查詢:編譯器會首先尋找乙個至少包含乙個名字為 twice 的實體作用域(類,檔案,或者名字空間),並將其中的候選實體列表。例子中,編譯器首先從物件 c 所在的類實體中進行查詢,找到就停止;如果沒找到就會依次在其基類和外圍的名字空間
中查詢,直到找到乙個至少含有乙個候選函式的作用域。兩點需要注意: 1) 只要找到乙個實體就停止查詢 ,所以並非所有的同名函式都會被考慮; 2) 引數所在名字空間也屬於查詢範圍(keoning 準則 ) 。
b) 過載決議:從所找到的候選過載函式列表中選出唯一最佳匹配 。如不唯一,就存在二義性。注意: 1) 這是基於名字查詢結果的; 2) 特化的模板函式不參與過載。
c) 可訪問性檢查:確定所選出的函式是否可訪問。這是最後一步,晚於過載決議。
後面將會有進一步的文章來介紹:如何確定c++每個編譯單元(cpp檔案)中的可見名字(與名字查詢相關);keoning查詢詳解; 過載 (overload) 和虛函式的重實現 (override).
C 編譯器的函式編譯流程
c 中的型別查詢過程相對簡單,基本上就是名字查詢,這裡不再介紹。對於 cpp 檔案中呼叫的乙個函式 或成員函式 編譯器主要做了下面三件事情 1 名字查詢 先在所在編譯單元中可見名字實體中進行名字查詢 1 類成員函式優先 物件所在的類 基類 一 經找到就停止查詢 2 如果沒有 在相應的名字空間中做進一...
C 編譯器的函式編譯流程揭秘
c 中的型別查詢過程相對簡單,基本上就是名字查詢,這裡不再介紹。對於 cpp 檔案中呼叫的乙個函式 或成員函式 編譯器主要做了下面三件事情 1 名字查詢 先在所在編譯單元中可見名字實體中進行名字查詢 1 類成員函式優先 物件所在的類 基類 一經找到就停止查詢 2 如果沒有 在相應的名字空間中做進一步...
揭秘 C 編譯器的函式編譯流程
c 中的型別查詢過程相對簡單,基本上就是名字查詢,這裡不再介紹。對於 cpp 檔案中呼叫的乙個函式 或成員函式 編譯器主要做了下面三件事情 1 名字查詢 先在所在編譯單元中可見名字實體中進行名字查詢 1 類成員函式優先 物件所在的類 基類 一經找到就停止查詢 2 如果沒有 在相應的名字空間中做進一步...