程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 友元函數在類中的聲明在外圍是不可見的,聲明

友元函數在類中的聲明在外圍是不可見的,聲明

編輯:C++入門知識

友元函數在類中的聲明在外圍是不可見的,聲明


捕獲.PNG 上圖所示在外圍的C類中聲明了兩個友元函數,f()和f(C<T> const&) 但是在main()函數中使用時,f()被提示沒有找到該函數的聲明, 但是f(*p)卻找到了函數的聲明 這是因為: 第一,C++標准規定友元聲明在類中,外圍作用域是不可見的 第二,C++可以根據ADL查找規則找到該函數的聲明 比如上面的f(*p)的形式參數是C<int> 那麼ADL查找的關聯集合就會包含 模板C實例化後的C<int>作用域,也就能夠找到函數f(C<int> const&);的聲明   好,那麼問題來了,為什麼f()函數不能根據ADL查找到聲明,f(*p)就可以? 仔細觀察這兩個函數,就會發現f()沒有參數,但是f(*p)有參數。   ADL查找規 ADL 全稱 Argument-Dependent Lookup 第一,使用此規則的函數必須要有參數 第二,使用此規則的函數名稱必須為非受限名稱,即名稱前面沒有顯式的出現 ->, ::, . 這三個限定符   如何查找 如果函數名稱後面有一個或多個實參表達式,那麼ADL將會查找這些實參的 關聯類 和 關聯名字空間 對於給定的類型,關聯類  關聯名字空間 所組成的集合的准確定義可以通過下列規則來確定: (1)對於基本類型(int, char等), 該集合為空集 (2)對於指針和數組類型,該集合是所引用類型的關聯類和關聯名字空間 (3)對於枚舉類型,名字空間是名字空間是枚舉聲明所在的名字空間,對於類成員,關聯類是枚舉所在的類 (4)對於class(包含聯合類型),關聯類包括該類本身,他的外圍類,直接基類,間接基類。關聯名字空間包括每個關聯類所在的名字空間。 (5)對於函數類型, 該集合包含所有參數類型和返回類型的關聯類和關聯名字空間 (6)對於類X的成員指針類型,除了包括成員相關的關聯名字空間,關聯類,該集合還包括與X相關的關聯名字空間和關聯類   此外ADL查找會忽略using關鍵字的名字空間。   自此,ADL會在所有的關聯類 和 關聯名字空間 依次查找直到找到符合的聲明。

 


當一個類聲明友元函數的時,函數的聲明不必是可見的這是什

說起來比較復雜,並且跟friend沒什麼關系
namespace A{ class C{}; void f(const C&); void f1(int);}int f2(){ f1(42);//因為沒有using A::f1,這樣的調用不會成功 A::C obj; f(obj);//但是因為obj的類型與命名空間A相關,這樣是可以成功編譯的}
 

友元函數只可以在類中聲明定義

友元函數必須在類中聲明,至於定義的函數體,你液可以寫到類外面去!布過不用再寫friend,只在聲明中寫friend即可!
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved