第28课 友元的尴尬能力
1. 友元的概念
(1)友元是C++中的一种关系,友元关系发生在函数与类之间或类与类之间
(2)友元关系是单项的,不能传递
class Point { double x; double y; friend void func(Point& p);//声明func为Point类的友元函数 } void func(Point& p){};//在这个函数中,可以访问Point类内的任何成员!
2. 友元的用法
(1)在类中以friend关键字声明友元
(2)类的友元可以是其它类或者具体函数
(3)友元不是类的一部分,也不受类中访问级别的限制,可以直接访问具体类的所有成员
(4)用友元的注意事项
①友元关系不具备传递性
②类的友元可以是其它类的成员函数(即其它类的成员函数作为该类的友元函数)
③类的友元可以是某个完整的类(即所有的成员函数都是友元)
【编程实验】友元的使用初探 28-1.cpp
#include <stdio.h> #include <math.h> class Point { private: double x; double y; public: Point(double x, double y) { this->x = x; this->y = y; } double getX(){return x;} double getY(){return y;} void getXY() { printf("x = %f, y = %f\n", x, y); } friend double Distance(Point& p1, Point& p2); }; //从这里看,Distance只是一个普通的函数 double Distance(Point& p1, Point& p2) { double ret = 0; ret=sqrt((p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y));//可以引用类中的私有成员! return ret; } int main() { Point p1(1, 2); Point p2(10, 20); p1.getXY(); p2.getXY(); printf("|(p1, p2)| = %f\n", Distance(p1, p2)); return 0; }
运行结果:
3. 友元的尴尬
(1)友元是为了兼顾C语言的高效而诞生的,但直接破坏了面向对象的封装性
(2)友元在实际产品中的高效是得不偿失的,在现代软件工程中己经逐渐被遗弃
【编程实验】友元的深入分析 28-2.cpp
#include <stdio.h> class ClassC { private: const char* n; public: ClassC(const char* n){this->n = n;} friend class ClassB; //B是C的友元类,即B可以任意访问C }; class ClassB { private: const char* n; public: ClassB(const char* n){this->n = n;} void getClassCName(ClassC& c) { printf("c.n = %s\n", c.n);//合法,因为在类C中,己将B声明为友元类 } friend class ClassA;//A是B的友元类,即A可以任意访问B }; class ClassA { private: const char* n; public: ClassA(const char* n){this->n = n;} void getClassCName(ClassC& c) { //printf("c.n = %s\n", c.n);//非合法,因为在类C中,并没将A声明为友元类 } void getClassBName(ClassB& b) { printf("b.n = %s\n", b.n);//合法,因为在类B中,己将A声明为友元类 } }; int main() { //A是B的友元类,B是C的友元类,但A不能自动传递为C的友元类 ClassA A("A"); ClassB B("B"); ClassC C("C"); A.getClassBName(B);//A是B的友元类, B.getClassCName(C);//B是C的友元类 return 0; }
运行结果:
4. 小结
(1)友元是为了兼顾C语言的高效而诞生的
(2)友元直接破坏了面向对象的封装性
(3)友元关系不具备传递性
(4)类的友元可以是其它类的成员函数
(5)类的友元可以是某个完整的类