C++ friend 函数和 friend 类

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

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

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++ program to demonstrate the working of friend function

#include <iostream>
using namespace std;

class Distance {
    private:
        int meter;
        
        // friend function
        friend int addFive(Distance);

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

// friend function definition
int addFive(Distance d) {

    //accessing private members from the friend function
    d.meter += 5;
    return d.meter;
}

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

输出

Distance: 5

在这里,addFive() 是一个友元函数,它可以访问私有公有数据成员。

虽然这个示例给了我们关于友元函数概念的 ধারণা,但它没有显示任何有意义的用途。

更有意义的用途是操作两个不同类的对象。这时友元函数就能非常有用。


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

// Add members of two different classes using friend functions

#include <iostream>
using namespace std;

// forward declaration
class ClassB;

class ClassA {
    
    public:
        // constructor to initialize numA to 12
        ClassA() : numA(12) {}
        
    private:
        int numA;
        
         // friend function declaration
         friend int add(ClassA, ClassB);
};

class ClassB {

    public:
        // constructor to initialize numB to 1
        ClassB() : numB(1) {}
    
    private:
        int numB;
 
        // friend function declaration
        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 进行前向声明。

// forward declaration
class ClassB;

C++ 中的友元类

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

class ClassB;

class ClassA {
   // ClassB is a friend class of ClassA
   friend class ClassB;
   ... .. ...
}

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

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

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

但是,我们不能从 ClassA 内部访问 ClassB 的成员。这是因为 C++ 中的友元关系是单向的,只授予,不被授予。


示例 3:C++ 友元类

// C++ program to demonstrate the working of friend class

#include <iostream>
using namespace std;

// forward declaration
class ClassB;

class ClassA {
    private:
        int numA;

        // friend class declaration
        friend class ClassB;

    public:
        // constructor to initialize numA to 12
        ClassA() : numA(12) {}
};

class ClassB {
    private:
        int numB;

    public:
        // constructor to initialize numB to 1
        ClassB() : numB(1) {}
    
    // member function to add numA
    // from ClassA and numB from ClassB
    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 的对象。


另请阅读

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战