2010-04-08 43 views
6

我想知道什麼C++名稱查找機制。什麼是名稱查找機制?

+0

首先谷歌結果:http://www.lysium.de/blog/index.php?/archives/3-C++-name-lookup-mechanism.html – 2010-04-08 22:58:26

+3

這是一個很大的問題。名稱查找是C++更復雜的一個方面。它的一些部分(Koenig lookup)甚至以人名命名,就好像新領地曾經被勘探者命名。 – 2010-04-08 22:58:53

+3

鮮爲人知的事實類型 - Andrew Koenig是名字出現在C++標準中的唯一人 - 3.4.2/ – 2010-04-08 23:06:12

回答

0

它的核心是編譯器用來確定給定名稱對應的過程 - 將其作爲變量或函數或其他語言結構。它必須找到名稱所指的基礎語言結構。

例如當您調用函數printf()時,編譯器必須找到printf的聲明,以便它瞭解它是什麼並且可以正確編譯它。

如前所述,C++使用各種名稱查找機制,您可以在Google上很容易地找到有關它們的信息。維基百科也有一些基本信息:http://en.wikipedia.org/wiki/Name_resolution

12

名稱查找是識別名稱意味着什麼的過程。名稱查詢的目的有兩個代碼

  • 確定正是你的代碼是什麼意思
  • 例如,如果你有這樣的代碼的

    • 歧義解析

      T(a); 
      

      這取決於是否T是否爲類型:如果是類型,則爲a的聲明,如果不是類型,則將其解釋爲函數c所有。

      某些名稱表示類型或模板。一般來說,無論何時遇到名稱,都必須在繼續解析包含它的程序之前確定該名稱是否表示這些實體之一。確定這個的過程稱爲名稱查找。

      名稱查找將名稱的使用與該名稱的聲明(3.1)相關聯。

      有名稱查找兩大類

      • 不合格的名稱查找是:從目前的範圍開始,一個名稱擡頭,如果一個類的內部逃逸到封閉範圍和基類。不從特定的命名範圍開始。該查找表格一找到名稱就會停止。因此,內部作用域(或類)中的名稱隱藏了在外部作用域(或基類)中找到的名稱。
      • 限定名稱查找:使用::運算符在給定範圍內查找名稱。

      其他一些形式存在,如查找該點或箭頭後會出現一個名稱(如ptr->foo)或查找在class foo名(其中無類型名稱將被忽略)。一種特別有趣的形式是argument dependent lookup,用於根據函數調用中使用的參數類型來查找函數聲明。

      名稱查找找到聲明後,會查看它的屬性以及程序是否可以使用它。

      只有名稱查找,函數重載解析(如果適用)和訪問檢查後,已成功通過名字的聲明引入的屬性在表達式處理進一步使用

      因此名稱查找會發現私有類成員,但是如果您使用這些名稱(如果您無法訪問它們),則代碼將被拒絕。即使基類與公共訪問具有相同的名稱,也是如此 - 這是因爲如果名稱在查找名稱時停止在派生類中,名稱查找將停止。

    +0

    關於不合格和合格的有趣點加上後期屬性檢查(其中令人頭痛的「超載方法隱藏正確的基礎」跳入。) 有趣的視頻通過Stl,關於名稱查詢: https://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n – 2012-11-04 16:33:38

    1

    我不知道你是否要求類比來描述名稱查找。但我會對上述問題給出一個可能的答案。 在深入研究名稱查找機制之前,我們先將兩個概念映射爲趣味和使用。

    1. 範圍 - >目錄
    2. 對象 - >文件

    我不想解釋這個比喻的原因。以下面的字面思考方式,範圍目錄每次範圍遇到。那麼對象文件

    #include <iostream> 
    
    using namespace std; 
    
    namespace Newton{ 
        double distance, time; 
        double velocity(const double &, const double &); 
    } 
    namespace Einstein{ 
        double distance, time; 
        double velocity(const double &, const double &); 
    } 
    
    int main() 
    { 
        using namespace Newton; 
        double s(10), t(10); 
        velocity(s,t); 
        return 0; 
    } 
    
    double Newton::velocity(const double & s, const double & t){ 
        distance = s; 
        time = t; 
        cout << "Calculation by Newton" << endl; 
        return distance/time; 
    } 
    
    double Einstein::velocity(const double & s, const double & t){ 
        distance = s; 
        time = t; 
        cout << "Calculation by Einstein" << endl; 
        return distance/time; 
    } 
    

    在這段代碼中,velocity是什麼執行?我們在main()的社交中遇到velocity功能。如果您在文件資源管理器中將其命名爲路徑名稱,則velocity實際上是/Main/velocity。當然,如果您檢查/Main/下的對象名稱,仍然有兩個雙重對象,st,以及一個名稱空間對象Newton。如果列出/Main/double/下的對象名稱,我認爲內置函數與名爲velocity的對象不匹配,這意味着,例如,不存在這樣的對象 - /Built-in Types/double/velocity。如果在/Main/Newton/下再次列出對象的名稱,則實際目錄搜索爲/Newton/,因爲它在那裏被聲明。然後,列出/Newton/下的對象名稱,我們找到兩個雙重對象,distancetime,以及一個名爲velocity的函數。是的,我們找到/Main/velocity的候選功能。

    我只能在C++中給出名稱查找的類比。爲了總結機制還有更多要補充的內容。