1. 程式人生 > >第28課 - 友元的尷尬能力

第28課 - 友元的尷尬能力

-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 25
friend 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課 - 友元的尷尬能力