C++ 友元函数和友元类

在本文中,您将学习在C ++中创建友元函数和友元类,并在程序中有效地使用它们。

OOP的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护的数据。

但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。因此,C ++编程内置了一种机制,可以从非成员函数访问私有或受保护的数据。

这是使用友元函数和友元类完成的。

C ++中的友元函数

如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。

通过使用关键字friend,编译器知道给定的函数是友元函数。

要访问数据,应该在类的内部以关键字friend开始声明友元函数(可以是类内部的任何地方,可以是private部分,也可以是public部分)。

C ++中的友元函数声明

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的友元函数。
    ... .. ...
}

示例1:友元函数的工作

/* 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函数的情况下操作两个不同类的对象,但是这个程序会很长,很复杂,很难理解。

示例2:使用友元函数添加两个不同类的成员

#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);

C ++编程中的友元类(friend class)

类似地,像一个友元函数一样,一个类也可以使用关键字friend成为另一个类的友元类。例如:

... .. ...
class B;
class A
{
   // class B 是 class A的友元类
   friend class B;
   ... .. ...
}

class B
{
   ... .. ...
}

当一个类成为另一个类的friend类(友元类)时,这就意味着这个类的所有成员函数都是另一个类的友元函数。

在这个程序中,B类的所有成员函数都是A类的朋友函数,因此B类的任何成员函数都可以访问A类的私有和受保护的数据,但是A类的成员函数不能访问B类的数据。

C ++编程中如何互为友元类

如何实现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的声明之后定义。