简要介绍C++编程中的友元函数和友元类
一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。现在,我们来补充介绍一个例外――友元(friend)。 fnend 的意思是朋友,或者说是好友,与好友的关系显然要比一般人亲密一些。有的家庭可能会这样处理:客厅对所有来客开放,而卧室除了本家庭的成员可以进人以外,还允许好朋友进入。在C++中,这种关系以关键宇 friend 声明,中文多译为友元。友元可以访问与其有好友关系的类中的私有成员,友元包括友元函数和友元类。如果您对友元这个名词不习惯,可以按原文 friend 理解为朋友即可。 在当前类以外定义的、不属于当前类的函数也可以在类中声明,但要在前面加 friend 关键字,这样就构成了友元函数。友元函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数。 友元函数可以访问当前类中的所有成员,包括 private 属性的。 1) 将普通函数声明为友元函数。 #include<iostream> using namespace std; class Student{ private: char *name; int age; float score; public: Student(char*,int,float); friend void display(Student &); //将display声明为友元函数 }; Student::Student(char *name,int age,float score){ this->name = name; this->age= age; this->score = score; } //普通成员函数 void display(Student &stu){ cout<<stu.name<<"的年龄是 "<<stu.age<<",成绩是 "<<stu.score<<endl; } int main(){ Student stu("小明",16,95.5f); display(stu); return 0; } 运行结果: 小明的年龄是 16,成绩是 95.5 请注意 display 是一个在类外定义的且没有使用 Student 作限定的函数,它是非成员函数,不属于任何类,它的作用是输出学生的信息。如果在 Student 类中未声明 display 函数为 friend 函数,它是不能引用 Student 中的私有成员 name、age、score 的。大家可以亲测一下,将上面程序中的第11行删去,观察编译时的信息。 现在由于声明了 display 是 Student 类的 friend 函数,所以 display 可以使用 Student 中的私有成员 name、age、score。但注意在使用这些成员变量时必须加上对象名,不能写成: cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl;
2) 将其他类的成员函数声明为友元函数 #include<iostream> using namespace std; class Address; //对Address类的提前引用声明 //声明Student类 class Student{ private: char *name; int age; float score; public: Student(char*,float); void display(Address &); }; //声明Address类 class Address{ private: char *province; char *city; char *district; public: Address(char*,char*,char*); //将Student类中的成员函数display声明为友元函数 friend void Student::display(Address &); }; Address::Address(char *province,char *city,char *district){ this->province = province; this->city = city; this->district = district; } //声明Student类成构造函数和成员函数 Student::Student(char *name,float score){ this->name = name; this->age= age; this->score = score; } void Student::display(Address &add){ cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl; cout<<"家庭住址:"<<add.province<<"省"<<add.city<<"市"<<add.district<<"区"<<endl; } int main(){ Student stu("小明",95.5f); Address add("陕西","西安","雁塔"); stu.display(add); return 0; } 运行结果: 小明的年龄是 16,成绩是 95.5 家庭住址:陕西省西安市雁塔区 在本例中定义了两个类 Student 和 Address。程序第 26 行将 Student 类中的成员函数 display 声明为友元函数,由此,display 就可以访问 Address 类的私有成员变量了。 两点注意: ② 程序中将 Student 类的声明和定义分开了,而将 Address 放在了中间,是因为 Student::display() 函数体中用到了 Address 类的成员,必须出现在 Address 类的类体之后(类体说明了有哪些成员)。 这里简单介绍一下类的提前声明。一般情况下,类必须在正式声明之后才能使用;但是某些情况下(如上例所示),只要做好提前声明,也可以先使用。 但是应当注意,类的提前声明的使用范围是有限的。只有在正式声明一个类以后才能用它去创建对象。如果在上面程序第4行后面增加一行: Address obj; //企图定义一个对象
请注意程序是在定义 Student::display() 函数之前正式声明 Address 类的。这是因为在 Student::display() 函数体中要用到 Address 类的成员变量 province、city、district,如果不正式声明 Address 类,编译器就无法识别这些成员变量。 ③ 一个函数可以被多个类声明为“朋友”,这样就可以引用多个类中的私有成员。 不仅可以将一个函数声明为一个类的“朋友”,而且可以将整个类(例如B类)声明为另一个类(例如A类)的“朋友”。这时B类就是A类的友元类。 友元类B中的所有函数都是A类的友元函数,可以访问A类中的所有成员。在A类的类体中用以下语句声明B类为其友元类: friend B;
friend 类名; 关于友元,有两点需要说明: 在实际开发中,除非确有必要,一般并不把整个类声明为友元类,而只将确实有需要的成员函数声明为友元函数,这样更安全一些。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |