• C++ 友元函数和友元类


    前言

            在本文中,您将学习在C ++中创建友元函数和友元类,并在程序中有效地使用它们。OOP的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护的数据。但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。因此,C ++编程内置了一种机制,可以从非成员函数访问私有或受保护的数据,这是使用友元函数和友元类完成的。

    C ++中的友元函数

            如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。通过使用关键字friend,编译器知道给定的函数是友元函数。要访问数据,应该在类的内部以关键字friend开始声明友元函数(可以是类内部的任何地方,可以是private部分,也可以是public部分)。

    C ++中的友元函数声明

    1. class class_name
    2. {
    3. ... .. ...
    4. friend return_type function_name(argument/s);
    5. ... .. ...
    6. }

    现在,您可以将友元函数定义为访问该类数据的普通函数。friend定义中未使用任何关键字。

    1. class className
    2. {
    3. ... .. ...
    4. friend return_type functionName(argument/s);
    5. ... .. ...
    6. }
    7. return_type functionName(argument/s)
    8. {
    9. ... .. ...
    10. // 可以从这个位置访问className的私有和受保护数据
    11. //因为此函数是className的友元函数。
    12. ... .. ...
    13. }

     

    1. /* C ++程序演示友元函数的工作。*/
    2. #include
    3. class base {
    4. public:
    5. // 友元函数
    6. friend int display_friend(base);
    7. private:
    8. int a = 1;
    9. protected:
    10. int b = 2;
    11. };
    12. // 友元函数的定义
    13. int display_friend(base m) {
    14. //从非成员函数访问私有数据和受保护数据
    15. int c = m.a + m.b;
    16. return c;
    17. }
    18. int main() {
    19. base base1;
    20. std::cout << "输出:" << display_friend(base1) << std::endl;
    21. system("pause");
    22. return 0;
    23. }

    输出结果:

    3

    分析:

            这里,友元函数display_friend() 在base类中声明。因此,可以从这个函数访问类中的私有数据和受保护数据。

    若将友元函数在类中的声明去掉,则程序会报错:
    去掉友元函数在类中的声明之后代码如下:

    1. /* C ++程序演示友元函数的工作。*/
    2. #include
    3. class base {
    4. public:
    5. // 友元函数
    6. //friend int display_friend(base);
    7. private:
    8. int a = 1;
    9. protected:
    10. int b = 2;
    11. };
    12. // 友元函数的定义
    13. int display_friend(base m) {
    14. //从非成员函数访问私有数据和受保护数据
    15. int c = m.a + m.b;
    16. return c;
    17. }
    18. int main() {
    19. base base1;
    20. std::cout << "输出:" << display_friend(base1) << std::endl;
    21. system("pause");
    22. return 0;
    23. }

    编译器报错: 

    使用友元函数添加两个不同类的私有或受保护成员变量

    1. #include
    2. class base2; // 类base2的前置声明
    3. class base1 {
    4. public:
    5. // 友元函数声明
    6. friend int display_friend(base1, base2);
    7. private:
    8. int a = 1;
    9. };
    10. class base2 {
    11. public:
    12. // 友元函数声明
    13. friend int display_friend(base1, base2);
    14. protected:
    15. int b = 2;
    16. };
    17. // 友元函数的定义
    18. // 函数display_friend()是类base1和base2的友元函数
    19. int display_friend(base1 m1, base2 m2) {
    20. //从非成员函数访问私有数据和受保护数据
    21. int c = m1.a + m2.b;
    22. return c;
    23. }
    24. int main() {
    25. base1 A;
    26. base2 B;
    27. std::cout << "输出:" << display_friend(A, B) << std::endl;
    28. system("pause");
    29. return 0;
    30. }

     输出结果:

    3

    分析:

            在这个程序中,类base1和base2已经将display_friend()声明为friend函数。因此,这个函数可以访问这两个类的私有数据或受保护数据。在这里,display_friend()函数将两个对象A和B的私有数据 a 和受保护数据 b 相加,并将其返回给main函数。

            为了使这个程序正常工作,应该像上面的实例中所示的那样,对一个类base2进行前置声明。这是因为使用以下代码在class base1中引用了class base2的友元函数:friend int display_friend(base1,base2);

    友元类(friend class)

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

    1. ... .. ...
    2. class B;
    3. class A
    4. {
    5. // class B 是 class A的友元类
    6. friend class B;
    7. ... .. ...
    8. }
    9. class B
    10. {
    11. ... .. ...
    12. }

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

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

    例如下面的代码:

    1. #include
    2. class B; // 前置声明
    3. class A {
    4. // class B 是class A的友元类
    5. friend class B;
    6. private:
    7. int a = 1;
    8. protected:
    9. int b = 2;
    10. };
    11. class B {
    12. public:
    13. // 类B的成员函数
    14. int displayB(A a1) {
    15. int c = a1.a + a1.b;
    16. return c;
    17. }
    18. };
    19. int main() {
    20. A a2;
    21. B b2;
    22. std::cout << b2.displayB(a2) << std::endl;
    23. }

    输出结果:

    3

    分析: 

            类B 为类A 的友元类,类B中的成员函数可以访问类A的私有数据和受保护数据。

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

            如何实现classA与B互为友元,即A可以访问B的私有,B也可以访问A的私有呢?案例如下:

    1. #include
    2. class B; // 前置声明
    3. class A {
    4. // class B 是class A的友元类
    5. friend class B;
    6. private:
    7. int a = 1;
    8. protected:
    9. int b = 2;
    10. public:
    11. int displayA(B);
    12. };
    13. class B {
    14. // class A 是class B 的友元类
    15. friend class A;
    16. public:
    17. // 类B的成员函数
    18. int displayB(A a1) {
    19. int c = a1.a + a1.b;
    20. return c;
    21. }
    22. private:
    23. int e = 3;
    24. protected:
    25. int f = 4;
    26. };
    27. // 类A的成员函数
    28. int A::displayA(B b1) {
    29. int g = b1.e + b1.f;
    30. return g;
    31. }
    32. int main() {
    33. A a2;
    34. B b2;
    35. std::cout << b2.displayB(a2) << std::endl; // 3
    36. std::cout << a2.displayA(b2) << std::endl; // 7
    37. }

    输出结果:
    3
    7

    互为友元类的做法就是,在class A中声明friend class B;在classB 中声明friend class A;

    注意:类A中使用到了类B的地方必须在类B的声明后定义,在类A中只能声明。例如上边类A中的displayA() 函数,不能在类A中直接定义,只能放在类B的声明之后定义。

  • 相关阅读:
    pnpm项目内网迁移技巧
    【论文笔记】UNet
    【c++刷题Day2】专题2线性DP
    ARM S5PV210的启动过程
    不得不说,还是这款开源工作流表单设计器较合心意!
    博客园美化显示效果
    JupyterNotebook设置Python环境的方法步骤
    北理工嵩天Python语言程序设计笔记(5 程序的控制结构)
    全志R128应用开发案例——点亮一颗 LED 灯
    解决CXF webService 调用报错: “Cannot create a secure XMLInputFactory”
  • 原文地址:https://blog.csdn.net/m0_48241022/article/details/133957626