在本文中,您将学习在C ++中创建友元函数和友元类,并在程序中有效地使用它们。
OOP的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护的数据。
但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。因此,C ++编程内置了一种机制,可以从非成员函数访问私有或受保护的数据。
这是使用友元函数和友元类完成的。
如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。
通过使用关键字friend,编译器知道给定的函数是友元函数。
要访问数据,应该在类的内部以关键字friend开始声明友元函数(可以是类内部的任何地方,可以是private部分,也可以是public部分)。
class class_name { ... .. ... friend return_type function_name(argument/s); ... .. ... }
现在,您可以将友元函数定义为访问该类数据的普通函数。friend定义中未使用任何关键字。
class className { ... .. ... friend return_type functionName(argument/s); ... .. ... } return_type functionName(argument/s) { ... .. ... // 可以从这个位置访问className的私有和受保护数据 //因为此函数是className的友元函数。 ... .. ... }
/* C ++程序演示友元函数的工作。*/ #include <iostream> using namespace std; class Distance { private: int meter; public: Distance(): meter(0) { } //友元函数 friend int addFive(Distance); }; // 友元函数的定义 int addFive(Distance d) { //从非成员函数访问私有数据 d.meter += 5; return d.meter; } int main() { Distance D; cout<<"距离: "<< addFive(D); return 0; }
输出结果
距离: 5
这里,友元函数addFive()在Distance类中声明。因此,可以从这个函数访问私有数据。
尽管此示例为您提供了有关友元函数概念的想法,但并未显示任何有意义的用途。
当您需要对两个不同类的对象进行操作时,将有一种更有意义的用法。那时,友元函数会非常有帮助。
你完全可以在不使用friend函数的情况下操作两个不同类的对象,但是这个程序会很长,很复杂,很难理解。
#include <iostream> using namespace std; // 前置声明 class B; class A { private: int numA; public: A(): numA(12) { } //友元函数声明 friend int add(A, B); }; class B { private: int numB; public: B(): numB(1) { } // 友元函数声明 friend int add(A , B); }; //函数add()是类A和B的友元函数 //访问成员变量numA和numB int add(A objectA, B objectB) { return (objectA.numA + objectB.numB); } int main() { A objectA; B objectB; cout<<"Sum: "<< add(objectA, objectB); return 0; }
输出结果
Sum: 13
在这个程序中,类A和B已经将add()声明为friend函数。因此,这个函数可以访问这两个类的私有数据。
在这里,add()函数将两个对象objectS和object的私有数据numA和numB相加,并将其返回给main函数。
为了使这个程序正常工作,应该像上面的实例中所示的那样,对一个类B进行前置声明。
这是因为使用以下代码在class A中引用了class B的友元函数:friend int add(A,B);
类似地,像一个友元函数一样,一个类也可以使用关键字friend成为另一个类的友元类。例如:
... .. ... class B; class A { // class B 是 class A的友元类 friend class B; ... .. ... } class B { ... .. ... }
当一个类成为另一个类的friend类(友元类)时,这就意味着这个类的所有成员函数都是另一个类的友元函数。
在这个程序中,B类的所有成员函数都是A类的朋友函数,因此B类的任何成员函数都可以访问A类的私有和受保护的数据,但是A类的成员函数不能访问B类的数据。
如何实现classA与B互为友元,即A可以访问B的私有,B也可以访问A的私有呢?案例如下:
#include <iostream> using namespace std; //必须提前声明class B不然编译会报错 class B; class A{ private: int a; public: friend class B; A(){ cout << "类A被构造" << endl; a = 20; } ~A(){ cout << "类A被析构" << endl; } void show(B & b); }; class B{ private: int b; public: friend class A; B(){ cout << "类B的构造" << endl; b = 12; } ~B(){ cout << "类B被析构" << endl; } void show(A &a){ cout << "a="<<a.a ; cout << " b=" <<b<<endl; } }; //函数不能放在class A 中,不然会编译报错 void A::show(B &b){ cout << "a="<<a ; cout << " b="<<b.b<< endl; } int main(){ A a; B b; a.show(b); b.show(a); return 0; }运行结果:
类A被构造 类B的构造 a=20 b=12 a=20 b=12 类B被析构 类A被析构
互为友元类的做法就是,在class A中声明friend class B;在classB 中声明friend class A;
注意:类A中使用到了类B的地方必须在类B的声明后定义,在类A中只能声明。例如左边类A中的show函数,不能在类A中直接定义,只能放在类B的声明之后定义。