倘若说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;
}