在 C++ 中,一个类中可以有 public、protected、private 三种属性的成员。
通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。
借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。
- 友元的关系是单向的而不是双向的。
- 友元的关系不能传递。
友元函数
在当前类以外定义的、不属于当前类的函数也可以在类中声明,但要在前面加 friend 关键字,这样就构成了友元函数。友元函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数。
友元函数可以访问当前类中的所有成员,包括 public、protected、private 属性的。
#include <iostream>using namespace std;class Student{public:Student(char *name, int age, float score);public:friend void show(Student *pstu); //将show()声明为友元函数private:char *m_name;int m_age;float m_score;};Student::Student(char *name, int age, float score):m_name(name), m_age(age), m_score(score){}//非成员函数void show(Student *pstu){cout<<pstu->m_name<<"的年龄是 "<<pstu->m_age<<",成绩是 "<<pstu->m_score<<endl;}//友元函数不同于类的成员函数,在友元函数中不能直接访问类的成员,必须要借助对象。//下面的写法是错误的:void show(){cout<<m_name<<"的年龄是 "<<m_age<<",成绩是 "<<m_score<<endl;}int main(){Student stu("小明", 15, 90.6);show(&stu); //调用友元函数Student *pstu = new Student("李磊", 16, 80.5);show(pstu); //调用友元函数return 0;}
#include <iostream>using namespace std;class Address; //提前声明Address类//声明Student类class Student{public:Student(char *name, int age, float score);public:void show(Address *addr);private:char *m_name;int m_age;float m_score;};//声明Address类class Address{private:char *m_province; //省份char *m_city; //城市char *m_district; //区(市区)public:Address(char *province, char *city, char *district);//将Student类中的成员函数show()声明为友元函数friend void Student::show(Address *addr);};//实现Student类Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){}void Student::show(Address *addr){cout<<m_name<<"的年龄是 "<<m_age<<",成绩是 "<<m_score<<endl;cout<<"家庭住址:"<<addr->m_province<<"省"<<addr->m_city<<"市"<<addr->m_district<<"区"<<endl;}//实现Address类Address::Address(char *province, char *city, char *district){m_province = province;m_city = city;m_district = district;}int main(){Student stu("小明", 16, 95.5f);Address addr("陕西", "西安", "雁塔");stu.show(&addr);Student *pstu = new Student("李磊", 16, 80.5);Address *paddr = new Address("河北", "衡水", "桃城");pstu -> show(paddr);return 0;}
友元类
将类 B 声明为类 A 的友元类,那么类 B 中的所有成员函数都是类 A 的友元函数,可以访问类 A 的所有成员,包括 public、protected、private 属性的。
#include <iostream>using namespace std;class Address; //提前声明Address类//声明Student类class Student{public:Student(char *name, int age, float score);public:void show(Address *addr);private:char *m_name;int m_age;float m_score;};//声明Address类class Address{public:Address(char *province, char *city, char *district);public://将Student类声明为Address类的友元类friend class Student;private:char *m_province; //省份char *m_city; //城市char *m_district; //区(市区)};//实现Student类Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){}void Student::show(Address *addr){cout<<m_name<<"的年龄是 "<<m_age<<",成绩是 "<<m_score<<endl;cout<<"家庭住址:"<<addr->m_province<<"省"<<addr->m_city<<"市"<<addr->m_district<<"区"<<endl;}//实现Address类Address::Address(char *province, char *city, char *district){m_province = province;m_city = city;m_district = district;}int main(){Student stu("小明", 16, 95.5f);Address addr("陕西", "西安", "雁塔");stu.show(&addr);Student *pstu = new Student("李磊", 16, 80.5);Address *paddr = new Address("河北", "衡水", "桃城");pstu -> show(paddr);return 0;}
