倘若说C++的类是一位女孩,她对于一切事物一切同仁,拒绝他们访问自己的内心,唯独“友元”,她不带一丝丝犹豫,展开自己的心扉。

友元是过程与封装的桥梁

在一些情况下,我们需要频繁的访问一个类的私有成员,那么就要频发的调用我们的接口函数,这里的开销是难以接受的。c++提供了一种解决方法——友元!通过友元,我们可以直接访问私有成员和保护成员。
但是使用友元要谨慎,正确的使用我们可以提高程序的流畅性,但是无限制的使用会导致程序的封装性和隐蔽性变差。

分类

友元函数

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数

如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend,如下所示:

class Box
{
   double width;
public:
   double length;
   friend void printWidth( Box box );//友元函数
   void setWidth( double wid );
};

友元成员

一个类的成员函数可以声明成另一个类的友元函数,这样的成员函数就叫友元成员
声明格式就比上面的友元函数多了个"类名::",当然这个类名是另一个了类的名称

//再某个类中
firend 函数返回值类型 类名::成员函数名(形式参数表);

友元类

成员都一个声明友元,类何尝不可以呢?友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是那个类的友元。
声明方法大致不变,类 ClassTwo 的所有成员函数作为类 ClassOne 的友元,需要在类 ClassOne 的定义中放置如下声明:

friend class ClassTwo;

综合举例

下面简单写了个十分经典的计算复数计算的函数,函数都是友元哇

#include<iostream>

class Complex {
    double real;//实部
    double image;//虚部
public:
    Complex(double r=0,double i=0)
    {real=r;image=i;}
    friend void inputcomplex(Complex &cmp);
    friend void outputcomplex(Complex &cmp);
    friend Complex addcomplex(Complex &c1,Complex &c2);
    friend Complex subcomplex(Complex &c1,Complex &c2);
    friend Complex mulcomplex(Complex &c1,Complex &c2);
};
void inputcomplex(Complex& cmp)//友元函数不用在定义的时候加上命名空间,她就不是这个类的成员
{
    std::cin>>cmp.real>>cmp.image;
}
void outputcomplex(Complex& cmp)//友元函数不用在定义的时候加上命名空间,她就不是这个类的成员
{
    std::cout<<cmp.real<<","<<cmp.image<<"i"<<std::endl;
}
Complex addcomplex(Complex& c1,Complex& c2)
{
    Complex t;
    t.real=c1.real+c2.real;
    t.image=c1.image+c2.image;
    return t;
}
Complex subcomplex(Complex& c1,Complex& c2)
{
    Complex t;
    t.real=c1.real-c2.real;
    t.image=c1.image-c2.image;
    return t;
}
Complex mulcomplex(Complex& c1,Complex& c2)
{
    Complex t;
    t.real=c1.real*c2.real-c1.image*c2.image;
    t.image=c1.real*c2.real+c1.image*c2.image;
    return t;
}


int main()
{
    Complex c1,c2,result;
    std::cout<<"请输入第一个复数的实部和虚部\n";
    inputcomplex(c1);
    std::cout<<"请输入第二个复数的虚部和虚部\n";
    inputcomplex(c2);
    result=addcomplex(c1,c2);
    std::cout<<"他们的和为\n";
    outputcomplex(result);
    result=subcomplex(c1,c2);
    std::cout<<"他们的差为\n";
    outputcomplex(result);
    result=mulcomplex(c1,c2);
    std::cout<<"他们的积为\n";
    outputcomplex(result);
    return 0;
}

努力成长的程序员