第28課 - 友元的尷尬能力
阿新 • • 發佈:2017-08-02
-a 成員 ace friend 能力 gif enter 都是 isp
第28課 - 友元的尷尬能力
1. 什麽是友元?
(1)友元是C++ 中的一種關系
(2)友元關系發生在函數與類之間或者類與類之間
(3)友元關系是單向的,不能傳遞
2. 友元的用法
(1)在類中以 friend 關鍵字聲明友元
(2)類的友元可以是其它類或者具體函數
(3)友元不是類的一部分
(4)友元不受類中訪問級別的限制
(5)友元可以直接訪問具體類的所有成員
3. 友元的語法
在類中用 friend 關鍵字對函數或類進行聲明。
1 #include <stdio.h> 2 #include <math.h> 3 4友元的使用初探class Point 5 { 6 double x; 7 double y; 8 public: 9 Point(double x, double y) 10 { 11 this->x = x; 12 this->y = y; 13 } 14 15 double getX() 16 { 17 return x; 18 } 19 20 double getY() 21 { 22 return y; 23 } 24 25friend double func(Point& p1, Point& p2); // 友元函數 26 }; 27 28 double func(Point& p1, Point& p2) 29 { 30 double ret = 0; 31 32 ret = (p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x); 33 34 ret = sqrt(ret); 35 36 return ret; 37 } 38 39 int main() 40 {41 Point p1(1, 2); 42 43 Point p2(10, 20); 44 45 printf("p1(%f, %f)\n", p1.getX(), p1.getY()); 46 printf("p2(%f, %f)\n", p2.getX(), p2.getY()); 47 printf("|(p1, p2)| = %f\n", func(p1, p2)); 48 49 return 0; 50 }
4. 友元的尷尬
(1)友元是為了兼顧 C 語言的高效而誕生的。
前面的例子中,計算兩點之間的距離,如果使用C語言開發,直接訪問結構體成員即可,效率很高。使用C++開發,如果按照一般的方式,需要多次調用 public 中的成員函數來訪問 private 中的成員變量,該例中就調用了8次 getX() / getY(),這樣就導致程序效率很低。早期的C++開發就是使用這種方式,然後被很多程序員所詬病,為了兼顧C語言的高效,由此誕生了友元。
(2)友元直接破壞了面向對象的封裝性,很多程序開發者將C++當作C語言使用了,將封裝性這樣的高級面向對象特性丟失了。
(3)友元在實際產品中的高效是得不償失的,在現代軟件工程開發中已經逐漸被遺棄
5. 註意事項
(1)友元關系不具備傳遞性。 A 是B 的友元,B 是C 的友元,但A 不 C 的友元。
(2)類的友元可以是其它類的成員函數
(3)類的友元可以是某個完整的類:所有的成員函數都是友元
1 #include <stdio.h> 2 3 class ClassC 4 { 5 private: 6 const char* n; 7 8 public: 9 ClassC(const char* n){this->n = n;} 10 11 friend class ClassB; //B是C的友元類,即B可以任意訪問C 12 }; 13 14 class ClassB 15 { 16 private: 17 const char* n; 18 19 public: 20 ClassB(const char* n){this->n = n;} 21 22 void getClassCName(ClassC& c) 23 { 24 printf("c.n = %s\n", c.n);//合法,因為在類C中,己將B聲明為友元類 25 } 26 27 friend class ClassA; //A是B的友元類,即A可以任意訪問B 28 }; 29 30 31 class ClassA 32 { 33 private: 34 const char* n; 35 36 public: 37 ClassA(const char* n){this->n = n;} 38 39 void getClassCName(ClassC& c) 40 { 41 //printf("c.n = %s\n", c.n);//非合法,因為在類C中,並沒將A聲明為友元類 42 } 43 44 void getClassBName(ClassB& b) 45 { 46 printf("b.n = %s\n", b.n);//合法,因為在類B中,己將A聲明為友元類 47 } 48 }; 49 50 int main() 51 { 52 //A是B的友元類,B是C的友元類,但A不能自動傳遞為C的友元類 53 ClassA A("A"); 54 ClassB B("B"); 55 ClassC C("C"); 56 57 A.getClassBName(B);//A是B的友元類, 58 B.getClassCName(C);//B是C的友元類 59 60 return 0; 61 }友元的深入分析
6. 小結
(1)友元是為了兼顧 C 語言的高效而誕生的
(2)友元直接破壞了面向對象的封裝性
(3)友元關系不具備傳遞性
(4)類的友元可以是其它類的成員函數
(5)類的友元可以是某個完整的類
第28課 - 友元的尷尬能力