AI智能
改变未来

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定义变量,所以要先声明类Aclass 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】:友元(黑马程序员)

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » C++ 友元类