一、引入友元机制的原因
1. 在不放弃私有数据安全性的情况下,使得类外部的函数或类能够访问类中的私有成员,在c++中就用友元作为实现这个要求的辅助手
段。
2. 声明了一个类的友元函数,就可以用这个函数直接访问该类的私有数据,从而提高了程序运行的效率。(如果没有友元机制,外部函
数访问类的私有数据,必须通过调用公有的成员函数才能访问私有数据,这在需要频繁调用私有数据的情况下,会带来较大的开销,
从而降低程序的运行效率)
3. 方便编程,在某些情况下,如运算符被重载时,需要用到友元函数。
4. 友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。
5. 友元既可以是不属于任何类的一般函数,也可以是另一个类的成员函数,还可以是整个的一个类(这个类中的所有成员函数都可以成
为友元函数)。
二、友元函数
声明格式:
friend 返回类型 函数名(参数表);
说明:
1. 声明友元函数时,可放在公共部分,也可放在私有部分;可定义在类内部,也可定义在类外部;
2. 友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类的所有对象的成员,包括私有成员和公有成
员;
3. 在类外部定义友元函数时,不必像成员函数那样,在函数名前加上“类名::”;(因为它不是成员函数)
4. 友元函数一般带有一个该类的入口参数,它必须通过作为入口参数传递进来的对象名或对象指针来引用该对象的成员;(因为友
元函数不是类的成员,所以它不能直接引用对象成员的名字,也不能通过this指针引用对象的成员)
例子:
[cpp:nogutter] view plaincopy
#include <iostream>
#include <string.h>
#include <cstdlib>
using namespace std;
class KGirl
{
char *name;
int age;
public:
KGirl(char *n, int d)
{
name = new char[strlen(n) + 1];
strcpy(name, n);
age = d;
}
friend void Disp(KGirl &); //声明友元函数
~KGirl()
{
delete name;
}
};
void Disp(KGirl &x) //定义友元函数
{
cout<<"girl/'s name is: "<<x.name<<", age: "<<x.age<<"/n";
}
int main()
{
KGirl e("Chen Xingwei",18);
Disp(e); //调用友元函数
return 0;
}
三、友元成员
定义格式:
friend 返回类型 函数所在类名::函数名(参数表);
说明:
1. 友元成员是指一个类的成员函数作为另一个类的友元函数;
2. 一个类的成员函数作为另一个类的友元函数时,必须先定义这个类;
3. 这种友元成员函数不仅可以访问自己所在类对象中的私有成员和公有成员,还可以访问friend声明语句所在类对象中的私有成员
和公有成员,这样能使两个类相互合作、协调工作,完成某一任务。
例子:
[cpp:nogutter] view plaincopy
#include <iostream>
#include <string.h>
#include <cstdlib>
using namespace std;
class KGirl; //向前引用
class KBoy
{
char *name;
int age;
public:
KBoy(char *n, int d)
{
name = new char[strlen(n) + 1];
strcpy(name, n);
age = d;
}
void Disp(KGirl &); //声明Disp()为类KBoy的成员函数
~KBoy()
{
delete name;
}
};
class KGirl
{
char *name;
int age;
public:
KGirl(char *n, int d)
{
name = new char[strlen(n) + 1];
strcpy(name, n);
age = d;
}
friend void KBoy::Disp(KGirl &); //声明类KBoy的成员函数Disp()为类KGirl的友元函数
~KGirl()
{
delete name;
}
};
void KBoy::Disp(KGirl &x) //定义友元函数Disp()
{
cout<<"boy/'s name is: "<<name<<", age: "<<age<<"/n"; //访问本类对象成员
cout<<"girl/'s name is: "<<x.name<<", age: "<<x.age<<"/n"; //访问友类对象成员
}
int main()
{
KBoy b("chen hao", 25);
KGirl e("zhang wei", 18);
b.Disp(e);
return 0;
}
程序结果:
boy's name is: chen hao, age: 25
girl's name is: zhang wei, age: 18
四、友元类
定义格式:
friend 类名;
说明:
1. 友元类的声明可放在类的公有部分,也可以放在私有部分;
2. 当一个类被说明为另一个类的友元时,它的所有的成员函数都可成为另一个类的友元函数,也就是说,作为友元的类中的所有
成员函数都可以访问另一个类中的私有成员;
3. 友元关系是单向的,不具有交换性,也不具有传递性。(如:类x是类y的友元,但类y不一定是类x的友元;类x是类y的友元
类y是类z的友元,则类x不一定是类z的友元)
例子:
[cpp:nogutter] view plaincopy
#include <iostream>
#include <string.h>
#include <cstdlib>
using namespace std;
class KGirl; //向前引用
class KBoy
{
char *name;
int age;
public:
KBoy(char *n, int d)
{
name = new char[strlen(n) + 1];
strcpy(name, n);
age = d;
}
void Disp(KGirl &); //声明Disp()为类KBoy的成员函数
~KBoy()
{
delete name;
}
};
class KGirl
{
char *name;
int age;
friend KBoy; //声明类KBoy是类KGirl的友元
public:
KGirl(char *n, int d)
{
name = new char[strlen(n) + 1];
strcpy(name, n);
age = d;
}
~KGirl()
{
delete name;
}
};
void KBoy::Disp(KGirl &x) //定义友元函数Disp(),它是类KBoy的成员函数,
//也是类KGirl的友元函数
{
cout<<"boy's name is: "<<name<<", age: "<<age<<"/n";
cout<<"girl's name is: "<<x.name<<", age: "<<x.age<<"/n";
}
int main()
{
KBoy b("chen hao", 25);
KGirl e("zhang wei", 18);
b.Disp(e);
return 0;
}
程序结果:
boy's name is: chen hao, age: 25
girl's name is: zhang wei, age: 18