为什么要有友元函数?简单地说,通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为public(共用的),然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它,c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。
除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员.
一、使用友元函数调用类成员
#include
#include
class girl{
private:
char *name;
int age;
public:
girl(char *n,int d)
{
name=new char[strlen(n)+1];
strcpy(name,n);
age=d;
}
friend void display(girl &); //声明为友元函数
~girl(){delete name;}
};
//定义友元函数, 这里把对象作为参数传递,为防止传值时,(对象)局部变量可能产生的巨大花费,一般以传引用的调用方式进行,若想保证源参数不被修改,可以加上const.
void display(girl &x){
cout<<"girl\'s name is:"<
}
void main()
{
girl a("Alice",24);
display(a); //调用友元函数
}
二、一个友元函数访问两个不同的类
#include
#include
using namespace std;
class boy; //需要先声明,因为girl成员函数中有对其的引用
class girl{
char name[25];
int age;
public:
void init(char N[],int A);
friend void prdata(const girl plg,const boy plb); //声明函数为girl类的友元函数
};
void girl::init(char N[],int A)
{
strcpy(name,N);
age=A;
}
class boy{
char name[25];
int age;
public:
void init(char N[],int A);
friend void prdata(const girl plg,const boy plb); //声明函数为boy类的友元函数
};
void boy::init(char N[],int A)
{
strcpy(name,N);
age=A;
}
void prdata(const girl plg , const boy plb)
{
cout<<"女孩"<
cout<<"男孩"<
}
void main()
{
girl G1,G2;
boy B1,B2;
G1.init("Alice",12);
B1.init("Bob",11);
prdata(G1,B2); //调用友元函数
}
三、使用友元成员函数访问另一个类
#include
#include
class girl; class boy{
char *name;
int age;
public:
boy(char *N,int A)
{
name=new char[strlen(N)+1];
strcpy(name,N);
age=A;
}
void disp(girl &);
};
class girl{
char *name;
int age;
public:
girl(char *N,int A)
{
name=new char[strlen(N)+1];
strcpy(name,N);
age=A;
}
friend void boy::disp(girl &); //声明类boy的成员函数disp()为类girl的友元函数
~girl(){delete name;}
};
void boy::disp(girl &x)
{
cout<<"boy\'s name is:"< //访问本类对象成员
cout<<"girl\'s name is:"< //访问友元类对象成员
}
void main()
{
boy b("jsfn_dai",25);
girl g("PY",18);
b.disp(g);
}
四、友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
friend class 类名;
其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。
例如,以下语句说明类B是类A的友元类:
class A
{
…
public:
friend class B;
…
};
经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。
使用友元类时注意:
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
例:
#include
#include
class girl;
class boy{
char *name;
int age;
public:
boy(char *n,int d)
{
name=new char[strlen(n)+1];
strcpy(name,n);
age=d;
}
void disp(girl &); //声明disp()为类boy的成员函数
~boy(){delete name;}
};
class girl{
char *name;
int age;
friend boy; //声明类boy是类girl的友元
public:
girl(char *n,int d)
{
name=new char[strlen(n)+1];
strcpy(name,n);
age=d;
}
~girl(){delete name;}
};
void boy::disp(girl &x) //定义函数disp()为类boy的成员函数,也是类girl的友元函数
{
cout<<"boy\'s name is:"<
cout<<"girl\'s name is:"<
}
void main()
{
boy b("jsfn_dai",25);
girl g("PY",18);
b.disp(g);
}