C++ 友元函数和友元类

在本教程中,我们将借助示例学习在 C++ 中创建友元函数和友元类。

数据隐藏是面向对象编程的一个基本概念。它限制了来自类外部的私有成员的访问。

同样,受保护的成员只能由派生类访问,而不能从外部访问。例如,

class MyClass {
    private:
        int member1;
}

int main() {
    MyClass obj;

    // Error! Cannot access private members from here.
    obj.member1 = 5;
}

然而,C++ 中有一个叫做友元函数的特性,它打破了这个规则,允许我们从类外部访问成员函数。

同样,还有一个友元类,我们将在本教程后面学习。

C++中的友元函数

一个友元函数可以访问私有受保护类的数据。我们在类的主体内使用 friend 关键字声明一个友元函数。

class className {
    ... .. ...
    friend returnType functionName(arguments);
    ... .. ...
}

示例 1:友元函数的工作

下面的 C++ 程序演示了友元函数的工作方式。

#include <iostream>
using namespace std;

class Distance {
    private:
        int meter;

        // 友元函数
        friend int addFive(Distance);

    public:
        Distance() : meter(0) {}

};

// 友元函数定义
int addFive(Distance d) {

    // 访问对象的私有属性
    d.meter += 5;
    return d.meter;
}

int main() {
    Distance D;
    cout << "Distance: " << addFive(D);
    return 0;
}

输出

Distance: 5

addFive() 是一个可以访问私有公共数据成员的友元函数。

尽管这个例子让我们对友元函数的概念有了一个概念,但它并没有显示出任何有意义的用途。

更有意义的用途是对两个不同类的对象进行操作。这时候友元功能就非常有用了。

示例 2:添加两个不同类的成员

该程序演示友元函数对了两个类的对象的操作。

#include <iostream>
using namespace std;

// 提前声明
class ClassB;

class ClassA {

    public:
        ClassA() : numA(12) {}

    private:
        int numA;

         // 友元函数声明
         friend int add(ClassA, ClassB);
};

class ClassB {

    public:
        ClassB() : numB(1) {}

    private:
        int numB;

        // 友元函数声明
        friend int add(ClassA, ClassB);
};

// access members of both classes
int add(ClassA objectA, ClassB objectB) {
    return (objectA.numA + objectB.numB);
}

int main() {
    ClassA objectA;
    ClassB objectB;
    cout << "Sum: " << add(objectA, objectB);
    return 0;
}

输出

Sum: 13

在这个程序中, ClassAClassB 都声明了 add() 为友元函数。因此,该函数可以访问两个类的私有数据。

这里要注意的一件事是 ClassA 里面的友元函数使用 ClassB, 但是,我们目前还没有定义 ClassB

// inside classA
friend int add(ClassA, ClassB);

为此,我们需要在我们的程序中提前声明 ClassB

// 提前声明
class ClassB;

C++ 中的友元类

我们还可以在 C++ 中使用 friend 关键字声明友元类。例如,

class ClassB;

class ClassA {
   // ClassB 是 ClassA 的友元类
   friend class ClassB;
   ... .. ...
}

class ClassB {
   ... .. ...
}

当一个类被声明为友元类时,友元类的所有成员函数都成为友元函数。

由于 ClassB 是友元类,我们可以从 ClassB 内部访问 ClassA 的所有成员。

但是,我们无法从 ClassA 内部访问 ClassB 的成员。这是因为 C++ 中的友元关系只被授予,而不是被接受。

示例 3:C++ 友元类

此程序演示了 C++ 友元类的工作方式。

#include <iostream>
using namespace std;

// 提前声明
class ClassB;

class ClassA {
    private:
        int numA;

        // 声明友元类
        friend class ClassB;

    public:
        // 构造函数,初始化 numA 为 12
        ClassA() : numA(12) {}
};

class ClassB {
    private:
        int numB;

    public:
        // 构造函数,初始化 numB 为 1
        ClassB() : numB(1) {}

    int add() {
        ClassA objectA;
        return objectA.numA + numB;
    }
};

int main() {
    ClassB objectB;
    cout << "Sum: " << objectB.add();
    return 0;
}

输出

Sum: 13

这里, ClassBClassA 的友元类。因此, ClassB 可以访问 classA.

ClassB 中,我们创建了一个函数 add() ,该函数返回 numAnumB 的和.

由于 ClassB 是友元类,我们可以在 ClassB 创建 ClassA 的对象.