C 使用类对数据进行隐藏和封装,类的数据成员一般定义为私有成员,而将提供类与外界通讯接口的成员函数定义为公有的。
C 类成员的三种访问权限:
- public:可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问;
- protected:可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问;
- private:可以被该类中的函数、友元函数访问,但不可以由子类的函数、该类的对象、访问。
但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁访问类的私有(private)成员和保护(protected)成员,这时可以将这些函数定义为友元函数。
除了友元函数,还有友元类,两者统称为友元(friend)。
借助友元,可以使得普通函数或其他类中的成员函数可以访问某个类的私有成员和保护成员。
- 友元函数:普通函数可以访问某个类私有成员或保护成员。
- 友元类:类A中的成员函数可以访问类B中的私有或保护成员。
友元函数时可以直接访问类的私有成员或保护成员,它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明。
友元函数的声明格式如下:
friend 类型 函数名(形参);
示例如下,友元函数 ShowAge() :
如上图所示,类的友元函数 ShowAge() 定义在类的外部,需要注意的是,尽管 ShowAge() 在类的定义中出现过,但其并不是类的成员函数。
倘若没有在 Student 类中声明友元函数 ShowAge() ,则其是不能直接访问类的私有成员的,如下图所示。
类的友元函数函数减少了类型检查和安全性检查,提高了程序的运行效率,但它破坏了类的封装性和隐藏性,使得非成员函数也可以访问类的私有成员。
2、友元类友元可以是一个函数,也可以是一个类,该类被称为友元类。
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的保护成员和私有成员。
声明友元类的格式如下:
friend class 类名;
其中,friend 和 class 是关键字,类名必须是程序中已经定义过的一个类。
示例如下,类CB是类CA的友元类,可以直接访问类CA的私有成员。
倘若没有在类CA中声明友元类CB,则CB是不能直接访问CA的私有成员的。
使用友元类时,需要注意:
- 友元关系不能被继承;
- 友元关系是单向的,不具有交换性。即类B是类A的友元,则类A不一定是类B的友元,需要看类中是否有相应的声明;
- 友元关系不具有传递性。即类B是类A的友元,类C是类B的友元,但类C不一定是类A的友元,需要看类中是否有相应的声明。
另外,使用一般不建议把整个类声明为友元类,而只将某些成员函数声明为友元函数,这样更安全些。
3、友元的优缺点利用 friend 修饰符,可以让一些普通函数 或 另一个类的成员函数 直接对某个类的保护成员和私有成员进行操作,提高了程序的运行效率;同时避免把类的成员都声明为public,最大限度地保护数据成员的安全。
但是,即使是最大限度地保护数据成员,友元也破坏了类的封装性。
如果将类的封装比喻成一堵墙的话,那么友元机制就像墙上开了一个门。所以使用友元时一定要慎重。