C++ 友元类

 

•概念

  类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。

  尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

  友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

  如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字  friend 

•全局函数做友元

样例1

  来看一个样例,如下所示:

#pragma warning(disable:4996)
#include<iostream>
#include<cstdio>
using namespace std;

class A
{
private:
    string priS = "我是类A的私有成员";//私有成员
protected:
    string proS = "我是类A的受保护的成员";//受保护的成员
};
void func(A& a)
{
    cout << a.priS << endl;                     
    cout << a.proS << endl;
}
int main()
{
    A a;
    func(a);
}

分析

  在该样例中,有一个类 A,A 中有两个属性,分别是 私有成员 priS , 受保护的成员 proS。

  对于全局函数 func() 而言,A中的这两个属性都是不可访问的,若要强行访问,编译阶段就不会通过:

  意思是,func() 不可以访问类A的私有成员和受保护的成员,那么,如何才能让 func() 访问到呢?

  只需要将 func() 定义为类A的友元函数即可,定义如下:

 friend void func(A& a); 

  将该定义放入类 A 中进行声明,你就可以在 func 中访问 A 的私有成员和受保护的成员了。

修改后的代码

#pragma warning(disable:4996)
#include<iostream>
#include<cstdio>
using namespace std;

class A
{
    friend void func(A& a);
private:
    string priS = "我是类A的私有成员";//私有成员
protected:
    string proS = "我是类A的受保护的成员";//受保护的成员
};
void func(A& a)
{
    cout << a.priS << endl;                     
    cout << a.proS << endl;
}
int main()
{
    A a;
    func(a);
}

•类做友元

样例2

#pragma warning(disable:4996)
#include<iostream>
#include<cstdio>
using namespace std;

class A
{
    friend class B;//声明B是A的友元类

private:
    string priS = "我是类A的私有成员";//私有成员
    void priF()
    {
        cout << "我是类A的私有函数" << endl;
    }
protected:
    string proS = "我是类A的受保护的成员";//受保护的成员
    void proF()
    {
        cout << "我是类A的受保护函数" << endl;
    }
};
class B
{
private:
    A a;
public:
    void func()
    {
        cout << "func可访问A的所有成员和函数" << endl;
        a.priF();
        a.proF();
        puts("");
        cout << a.priS << endl;
        cout << a.proS << endl;
    }
};

int main()
{
    B b;
    b.func();
}

分析

  在类A中,通过  friend class B;  语句,将B定义为A的友元类,那么,B中的任何成员和成员函数都可以访问A的私有的和受保护的成员或函数。

•成员函数做友元

样例3

#pragma warning(disable:4996)
#include<iostream>
#include<cstdio>
using namespace std;

class A;//B中使用了类A定义变量,所以要先声明类A
class B
{
private:
    A* a;//此处的 a 必须是 A* 类型
public:
    B();
    void func();
};

class A//因为类A中用到了类B中的func,所以类B的声明要在类A的前面
{
    friend void B::func();//声明B中的成员函数func作为A的友元函数

private:
    string priS = "我是类A的私有成员";//私有成员
    void priF()
    {
        cout << "我是类A的私有函数" << endl;
    }
protected:
    string proS = "我是类A的受保护的成员";//受保护的成员
    void proF()
    {
        cout << "我是类A的受保护函数" << endl;
    }
};


B::B()
{
    a = new A();//对a进行初始化,必须要在A声明后才能进行,所以类B的构造函数要放在类A的下面
}
void B::func()//因为该函数使用了类A中的成员,所以,要在类外定义该函数且要放到类A下面
{
    cout << "func可访问A的所有成员和函数" << endl;
    a->priF();
    a->proF();
    puts("");
    cout << a->priS << endl;
    cout << a->proS << endl;
}
int main()
{
    B b;
    b.func();
}

注意

  1. 注意类A和类B的声明顺序

  2. 类B中的函数要在类外进行定义,且要放到类A的声明后

•参考资料

  【1】:C++ 友元函数(菜鸟教程)

  【2】:友元(黑马程序员)

posted @ 2022-03-08 16:16  MElephant  阅读(271)  评论(0编辑  收藏  举报