C++中的友元函数

正如我们已经知道的,在面向对象的编程语言中,类的成员可以访问类的数据和函数,但外部函数无法访问类的数据。然而,有时候外部函数需要访问类的私有成员,这时候就需要用到友元函数。

什么是友元函数?

友元函数是在类的范围之外定义的函数,但它具有访问类的所有私有和保护成员的权限。

友元函数出现在类的定义中,但友元函数本身是成员函数。

友元函数的特点:

  1. 友元函数不在其被声明为友元的类的作用域内。
  2. 不能使用对象调用友元函数,因为它不在该类的作用域内。
  3. 可以像普通函数一样调用友元函数,无需使用对象。
  4. 不能直接访问成员名称,而必须使用对象名和成员名的点成员运算符。
  5. 友元函数可以在类的私有或公有部分声明。

为什么我们需要在C++中使用友元函数?

  • 在C++中,友元函数用于直接访问类的私有数据,而不使用该类的对象。
  • 友元函数还用于执行运算符重载。就像我们已经了解到的函数重载一样,运算符也可以通过运算符重载进行重载。

友元函数的特点:

  1. 友元函数使用friend关键字声明。
  2. 它不是类的成员,但是它是类的友元。
  3. 由于它不是类的成员,因此可以像普通函数一样定义。
  4. 友元函数不能直接访问类的数据成员,而是将一个对象作为参数传递。
  5. 它类似于普通函数。
  6. 如果我们想在函数中共享多个类的数据,则可以使用友元函数。

友元函数声明的语法如下:

class class_name      
{      
    friend data_type function_name(argument/s);            // 友元函数的语法    
};      

在上述声明中,友元函数前面带有关键字friend。该函数可以像普通的C++函数一样在程序的任何地方定义。函数定义不使用关键字friend或作用域解析运算符。

让我们通过一个例子来理解友元函数。

#include <iostream>  
using namespace std;  
class Distance  
{  
    private:  
    int meters;  
    public:  
    // 构造函数  
    Distance()  
    {  
        meters = 0;  
    }  
    // display_data() 方法的定义  
    void display_data()  
    {  
        std::cout << "Meters value : " << meters<<std::endl;  
    }  
    
    // 友元函数的原型。  
    friend void addvalue(Distance &d);  
    
};  

// 友元函数的定义  
void addvalue(Distance &d) // 参数包含引用  
{  
    d.meters = d.meters+10; // 将meters的值增加10  
}  

// main() 方法  
int main()  
{  
    Distance d1; // 创建Distance类的对象  
    d1.display_data(); // meters = 0  
    addvalue(d1); // 调用友元函数  
    d1.display_data(); // meters = 10  
    return 0;  
}  

在上面的代码中,Distance是一个类,它包含名为'meters'的私有字段。Distance()是构造函数,它将'meters'的值初始化为0。display_data()是一个方法,用于显示'meters'的值。addvalue()是Distance类的友元函数,用于修改'meters'的值。在main()方法中,d1是Distance类的对象。

输出:

1.png

友元函数在处理两个不同类的对象时也非常有用。

让我们通过一个例子来理解。

// 使用友元函数将两个不同类的成员相加
#include <iostream>
using namespace std;
// 类的前向声明
class ClassB;

// 类的声明
class ClassA {
 public:
        // 构造函数 ClassA() 将 num1 初始化为 12
        ClassA()
        {
            num1 = 12;

        }

    private:
        int num1;  // 整数变量的声明

         // 友元函数声明
         friend int multiply(ClassA, ClassB);
};
class ClassB {
public:
        // 构造函数 ClassB() 将 num2 初始化为 2
        ClassB()
        {
            num2 = 2;
        }
    private:
        int num2;  // 整数变量的声明
 // 友元函数声明
        friend int multiply(ClassA, ClassB);
};

// 访问两个类的成员
int multiply(ClassA object1, ClassB object2)
{
    return (object1.num1 * object2.num2);
}

int main() {
    ClassA object1;   // ClassA对象的声明
    ClassB object2;   // ClassB对象的声明
    cout << "两个数相乘的结果为: " << multiply(object1, object2);
    return 0;
}

在上述代码中,我们定义了两个名为ClassA和ClassB的类。由于ClassA被声明为ClassB的友元,因此ClassA可以访问ClassB的所有数据成员。在ClassB中,我们定义了一个名为add()的函数,它返回num1和num2的和。由于ClassB被声明为ClassA的友元,因此我们可以在ClassB中创建ClassA的对象。

正如我们在上述代码中观察到的,ClassA中的友元函数也在没有先前声明ClassB的情况下使用了ClassB。因此,在这种情况下,我们需要提供ClassB的前向声明。

输出:

2.png

友元类在C++中

也可以通过friend关键字创建。

class Class1;  
class Class2  
{  
  // Class1是Class2的友元类  
     friend class Class1;  
     .. .....  
};  
class Class1  
{  
   ....  
};  

在上述声明中,Class1被声明为Class2的友元类。Class1可以访问Class2的所有成员。

让我们通过一个例子来理解友元类。

// C++程序,演示友元类的工作  
#include <iostream>  
using namespace std;  
// 前向声明  
class ClassB;  
  
class ClassA {  
    private:  
        int num1;  
  
        // 声明友元类  
        friend class ClassB;  
  
    public:  
        // 构造函数,将numA初始化为10  
        ClassA()  
        {  
            num1 = 10;   
        }  
};  
  
class ClassB {  
    private:  
        int num2;  
  
    public:  
        // 构造函数,将numB初始化为1  
        ClassB()  
        {  
            num2 = 1;   
        }  
      
    // 成员函数,将num1和num2相加  
    int add() {  
        ClassA objectA;  
        return objectA.num1 + num2;  
    }  
};  
  
int main() {  
    ClassB objectB;  
    cout << "Sum: " << objectB.add();  
    return 0;  
}  

在上面的代码中,我们创建了两个名为ClassA和ClassB的类。由于ClassA被声明为ClassB的友元类,所以ClassA可以访问ClassB的所有数据成员。在ClassB中,我们定义了一个名为add()的函数,它返回num1和num2的和。由于ClassB被声明为ClassA的友元类,所以我们可以在ClassB中创建ClassA的对象。

输出:

3.png

标签: C++语言, C++语言教程, C++语言技术, C++语言学习, C++语言学习教程, C++语言下载, C++语言开发, C++语言入门教程, C++语言进阶教程, C++语言高级教程, C++语言面试题, C++语言笔试题, C++语言编程思想