生學(xué)C++編程語法知識(C++中的友元函數(shù)(friend function)))
C中的友元函數(shù)friend function——為什么一個“外人”可以進(jìn)入類的私密房間同學(xué)們我們以前學(xué)習(xí)過封裝類把自己的數(shù)據(jù)保護(hù)起來外面的人不能隨便訪問。例如class Student { private: int score; public: Student(int s) { score s; } };這里score是私有成員。外面Student s(100); cout s.score;會報錯。為什么因為private私有成員只允許類自己訪問。但是有一天出現(xiàn)一個特殊情況有一個“外人”雖然不是這個類的成員但是特別可靠希望它能夠訪問 private。怎么辦C提供了friend友元一、什么是友元函數(shù)一句話友元函數(shù)是一個普通函數(shù)但是類允許它訪問自己的私有成員。注意它不是類的成員函數(shù)。它只是普通函數(shù) 特殊權(quán)限例如#include iostream using namespace std; class Student { private: int score; public: Student(int s) { score s; } friend void show(Student s); }; void show(Student s) { cout s.score endl; } int main() { Student stu(100); show(stu); }輸出100為什么因為雖然show()不是 Student 的成員函數(shù)。但是Student說friend void show(Student s);意思是我允許這個函數(shù)訪問我的秘密。所以s.score可以訪問。二、沒有友元會怎樣如果沒有friend那么void show(Student s) { cout s.score; }編譯錯誤score is private因為普通函數(shù)沒有權(quán)限。三、生活中的例子假設(shè)你有一個小保險箱。里面private: 金幣 密碼 日記普通同學(xué)不能打開。但是你的爸爸你告訴他密碼friend 爸爸于是爸爸可以打開。注意爸爸不是保險箱的一部分。但是擁有特殊權(quán)限。這就是友元。四、友元函數(shù)為什么必須在類里面聲明這是很多初學(xué)者疑惑的問題。例如為什么不能class Student { private: int score; }; friend void show(Student s);這樣寫答案因為friend是一種“授權(quán)聲明”。授權(quán)必須由擁有東西的人發(fā)出。我們舉生活例子你的房子房主小明。小明說我允許張三進(jìn)入我的房子。這個聲明必須由小明說。不能張三自己說我宣布我是小明家的朋友所以我可以進(jìn)去。不行。C也是一樣類擁有private成員所以必須由類聲明friend void show(Student s);表示“我允許show訪問”。五、友元聲明在哪里寫通常寫在class內(nèi)部例如class Student { private: int score; public: friend void show(Student s); };位置其實private下面public下面都可以。例如這樣也可以class Student { public: friend void show(Student s); private: int score; };因為friend聲明不受private/public影響。六、friend聲明只是授權(quán)不代表函數(shù)屬于類這是重點很多學(xué)生容易誤解看到friend void show(Student s);以為show是Student的方法。錯誤真正的成員函數(shù)class Student { public: void show(); };調(diào)用stu.show();友元函數(shù)friend void show(Student);調(diào)用show(stu);區(qū)別成員函數(shù)友元函數(shù)屬于類嗎是不是調(diào)用方式對象.函數(shù)()普通函數(shù)()能訪問private嗎可以可以需要friend嗎不需要需要七、為什么需要友元函數(shù)那么問題來了既然破壞封裝為什么還要存在主要有幾個原因。1. 兩個類需要互相合作例如有class A { private: int x; }; class B { private: int y; };如果A需要訪問B內(nèi)部數(shù)據(jù)。怎么辦可以friend class A;2. 運算符重載這是最常見用途。例如我們想cout student;輸出學(xué)生信息。實際上cout左邊是ostream。不是Student。所以通常寫friend ostream operator(ostream, Student);例如class Student { private: int score; public: Student(int s) { scores; } friend ostream operator(ostream out, Student s); }; ostream operator(ostream out, Student s) { outs.score; return out; }使用Student s(99); couts;輸出99八、友元函數(shù)會破壞封裝嗎這是一個經(jīng)典問題。答案會降低封裝性但是有時候非常方便。為什么因為private本來是“不讓別人看”。friend相當(dāng)于“給某個人開后門”。所以不要大量使用。原則能不用friend就不用friend。 必須合作時再使用friend。九、友元函數(shù)和成員函數(shù)的區(qū)別考試重點例如class A { private: int x; public: void f(); friend void g(A); };其中f()成員函數(shù)特點a.f();內(nèi)部有隱藏參數(shù)this指針g()友元函數(shù)普通函數(shù)g(a);沒有this指針十、小學(xué)生記憶口訣 ?什么是友元不是家庭成員 但是擁有鑰匙。為什么類里面聲明誰家的秘密 誰決定開放。friend特點friend不是成員 但是能訪問private。不要濫用friend是一把鑰匙 鑰匙越多家越不安全。十一、考點總結(jié)看到friend void fun();記住? fun不是成員函數(shù)? fun可以訪問private? 必須在類內(nèi)部聲明? 類外定義? 不需要對象調(diào)用一句話總結(jié)友元函數(shù)是類授予某個普通函數(shù)的特殊訪問權(quán)限它不是類成員卻可以訪問類的private成員。因為權(quán)限來自類本身所以必須由類內(nèi)部進(jìn)行friend聲明而不能由外部自己聲明。這也是 C 面向?qū)ο笾小胺庋b與特殊開放”的一個重要設(shè)計思想。