新的概念:类的友元
回顾:类成员访问控制方式使得普通函数无法直接访问类的私有成员或保护成员,一个类中的成员函数也无法直接访问另一个类的私有成员或保护成员。
问题:在程序中,如果普通函数或另一个类中的函数需要经常通过类提供的公有接口来访问类的私有或保护成员,这种方式会带来很多不便,那么如何提高程序运行的效率呢?
答:可以将它们声明为类的友元——朋友,它们就可以直接访问类的任何成员了。(友元提供了一个一般函数与类成员之间,不同类的成员之间进行数据共享的机制)
友元的而三种形式:
- 友元函数(将普通函数声明为类的友元函数的形式)
friend <数据类型> <友元函数名>(参数表);
例:将普通函数 “int fun(int x);” 声明为A类的友元函数
(声明后,该函数有权访问A类中的任何成员)
class A
{
friend int fun (int x); //声明普通函数为友元函数
};
- 友元成员(将一个类的成员函数声明为另一个类的友元函数)
fried <类型><含有友元成员的类名>::<友元成员名>(参数表);
例:将A类中的成员函数"int fun (int x)"声明为B类的友元函数
(声明后,该函数有权访问B类中的任何成员)
class A
{
……
int fun(int x);
……
};
class B
{
……
friend int A::fun(int x); //函数是B的友元函数,就在B处声明
……
};
- 友类(将一个类声明为另一个类的友类)
friend <友类名>; 或 friend class <友类名>;
例:将A类声明为B类的友类
(声明后,A类的任何成员函数都有权访问B类中的任何成员)
class B
{
friend class A; //A是B的友类,便在B中声明
}
友元使用示例说明:
- 普通函数getStudentInfo()声明为学生类的友元函数
- 教师可以修改学生成绩,便将其成员函数SetScore()声明为学生类的友元成员
- 管理员对学生具有更多的操作权限,所以将其声明为学生的友类
//DenfineClass.h
class Student;
void getStudentInfo(Student &s);
class Teacher
{
public:
void SetScore(Student &s,double sc); //设置指定学生的成绩
private:
long m_number; //教工号
char m_name[10]; //教工姓名
};
class Manager
{
public:
void ModifyStudentInfo(Student &s,long,char*,double);
//修改学生的信息——学号,姓名,成绩
private:
long m_number; //管理员号
char m_name[10]; //管理员姓名
};
class Student
{
public:
friend void getStudentInfo(Student &s);//声明友元函数
friend void Teacher::SetScore(Student &s,double sc);//声明友元成员
friend class Manager;//声明友类
double GetScore()
{
return m_score;
}
private:
long m_number;
char m_name[10];
double m_score;
};
//DefineClass.cpp
#include "DefineClass.h"
#include <string>
#include <iostream>
using namespace std;
void Teacher::SetScore(Student &s,double sc)//Stuent &s表示学生对象的引用
{
s.m_score=sc;//直接访问学生对象s的私有成员m_score
}
void Manager::ModifyStudent(Student &s,long number,char* name,double score)
{
s.m_number=number;//直接访问学生对象s的私有成员m_number
strcpy(s.m_name,name);//直接访问学生对象s的私有成员m_name
s.m_score=score;//直接访问学生对象s的私有成员m_score
}
void getStudentInfo(Student &s)
{
cout<<"Number:"<<m_nubmer<<endl;;
cout<<"Name:"<<m_name<<endl;
cout<<"Score:"<<m_score<<endl;
}
//testFridentMember.cpp
#include <iostream>
#include "DefineClass.h"
using namespace std;
int main()
{
Teacher t;
Manager m;
Student s;
t.SetScore(s,85.5);
m.ModifyStudentInfo(s,19870110,"jennie",100);
getStudentInfo(s);
return 0;
}