一、前言:
有时候,普通函数需要直接访问一个类的私有或者保护成员。如果没有友元机制的话,那么只有把这些成员的权限设置为公共的,从而,任何函数都可以无拘束的访问它了。为了同时可以保护类的私有成员,又可以实现数据共享,所以就可以使用友元机制了。

二、友元通常使用场景

  • 运算符重载某些地方,使用友元(后面博客会讲这方面的内容)
  • 两个类数据共享的时候,使用友元

三、友元的使用
注意事项:

  • 如果访问类的非静态成员时,需要友元提供一个对象作为参数,才可以访问
  • 如果访问类的静态成员时,不需要参数

  • 普通友元函数
    目的:使用普通函数,就可以访问类的私有成员。
    例子:

#include<iostream>
#include<string>
using namespace std;

class Student
{
private:
    string name;
    int age;
    static int num;
public:
    Student(string s, int a)
    {
        name = s;
        age = a;
    }
    friend void print_no_static(const Student &);     //通过友元函数,打印出所有的非静态成员
    friend void print_static();                      //通过友元函数,打印出所有的静态成员

};
int Student::num = 10;
void print_no_static(const Student & s)
{
    cout << "非静态成员:" << endl;
    cout << "name: " << s.name << endl;
    cout << "age: " << s.age << endl;
}
void print_static()
{
    cout << "静态成员:" << endl;
    cout << "num= " << Student::num << endl;
}

void main()
{
    Student s("Ouyang", 21);
    print_no_static(s);
    print_static();
    system("pause");

}

输出结果:
c++中的友元详解_c++类的基础知识

作为普通函数,其实现是在类的外部,调用则是直接按照正常的函数调用。

  • 类成员中的一个成员函数,作为另外一个类的友元函数
    目的:该函数需要访问另外一个类的私有或者保护成员,比对其进行一些操作。现实生活中的一个例子就是:老师类需要对学生的成绩进行修改。
    例子:
#include<iostream>
#include<string>
using namespace std;
class Student;
class Teacher
{
public :
    void change_student_grade(Student & s);     //定义一个成员函数
};
class Student
{
private:
    int grade;
    string name;
public:
    Student(string s, int g)
    {
        grade = g;
        name = s;
    }
    friend void Teacher::change_student_grade(Student & s);     //声明该成员函数为Student的友元函数
    void print()
    {
        cout << "name= " << name << endl;
        cout << "grade=  " << grade << endl;
    }
};
void Teacher::change_student_grade(Student & s)                 //实现该友元函数
{
    s.grade = 95;
}

int main()
{
    Student s("Ouyang", 100);
    Teacher t;
    cout << "修改前:" << endl;
    s.print();
    t.change_student_grade(s);
    cout << "修改后:" << endl;
    s.print();
    system("pause");
    return 0;
}

输出结果:
c++中的友元详解_友元_02
一个类的成员函数作为另外一个类的成员函数时,函数的声明在类内,实现还是在类外。

  • 友元类
    目的:使用单个声明使Y类的所有函数成为类X的友元,它提供一种类之间合作的一种方式,使类Y的对象可以具有类X和类Y的功能。

例子:

#include<iostream>
#include<string>
using namespace std;


class Student;
class Teacher
{
public :
    void print(Student & s);
};
class Student
{
private:
    int age;
    string name;
    friend Teacher;                //声明Teacher为Student的友元类
public :
    Student(string s, int a)
    {
        name = s;
        age = a;
    }
};
void Teacher::print(Student & s)
{
    cout << "name: " << s.name << endl;
    cout << "age: " << s.age << endl;
}

int main()
{
    Student s("Ouyang", 21);
    Teacher t;
    t.print(s);
    system("pause");
    return 0;
}

输出结果:
c++中的友元详解_友元_03

四、友元函数和类成员函数的区别

  1. 成员函数有this指针,而友元函数没有this指针。
  2. 友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。