友元
C++中的友元为数据隐藏这堵不透明的墙 开了一个小孔,外界可通过这个小孔窥 视类内部的秘密,友元是一扇通向私有 成员的后门
友元可分为:友元函数 友元成员 友元类
友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访 问该类的所有对象的成员,包括私有成 员和公有成员
在类定义中声明友元函数时,需在其函 数名前加上关键字friend。此声明可以 放在公有部分,也可以放在私有部分。 友元函数可以定义在类的内部,也可以 定义在类的外部
友元的利弊
友元不是类成员,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。不过,类的访问权限确实在某些应用场合显得有些呆板,从而容忍了友元这一特别语法现象。
友元函数
class Girl {
char *name;
int age;
public:
Girl(char *name, int age):age(age) {
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
}
friend void disp(Girl &); //声明为友元函数
};
void disp(Girl &x) {
cout<<x.name<<endl;
cout<<x.age<<endl;
}
Girl girl("zhangsan", 10);
disp(girl);
友元成员
// 使用友元成员函数访问另一个类
#include <iostream>
#include <cstring>
using std::cin;
using std::cout;
using std::endl;
class Girl; //向前引用
//class Boy;
class Boy{
private:
char *name;
int age;
public:
Boy(char *N,int A){
name = new char[strlen(N)+1];
strcpy(name,N);
age = A;
}
void disp(Girl &); //声明disp()为类boy的成员函数
~Boy(){
delete name;
}
};
class Girl{
private:
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:"<<name<<",age:"<<age<<endl; //访问本类对象成员
cout<<"girl\'s name is:"<<x.name<<",age:"<<x.age<<endl; //访问友元类对象成员
}
int main()
{
Boy b("chen hao",25);
Girl g("zhang wei",18);
b.disp(g);
return 0;
}
友元类
//boy为girl的友元类
#include <iostream>
#include <cstring>
using std::cin;
using std::cout;
using std::endl;
class Girl;
class Boy{
private:
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的成员函数
void test(Girl &g);
~Boy(){
delete name;
}
};
class Girl{
private:
char *name;
int age;
friend class 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:"<<this->name<<",age:"<<age<<endl;
cout<<"girl\'s name is:"<<x.name<<",age:"<<x.age<<endl;
}
void Boy::test(Girl & g)
{
cout<<"in boy test "<<g.name<<endl;
}
int main()
{
Boy b("chen hao",25);
Girl g("zhang wei",18);
b.disp(g);
b.test(g);
return 0;
}
注意事项
(1)友元关系不能被继承。
(2)友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3)友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明