• 33.友元


            类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?

            解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解:

            比如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。

            程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。

    1. 全局函数作友元函数

            友元函数的目的:访问类中的私有成员属性

    1. #include
    2. #include
    3. using namespace std;
    4. class Building {
    5. //让全局函数:好朋友函数 变成友元函数
    6. friend void goodfriend(Building* building);
    7. public:
    8. string m_room; //客厅
    9. Building()
    10. {
    11. this->m_Bedroom = "卧室";
    12. this->m_room = "客厅";
    13. }
    14. private:
    15. string m_Bedroom; //卧室
    16. };
    17. //全局函数 好朋友
    18. void goodfriend(Building * building) {
    19. cout << "好朋友正在参观" << building->m_room << endl;
    20. cout << "好朋友正在参观" << building-> m_Bedroom << endl;
    21. }
    22. void test()
    23. {
    24. Building* building = new Building;
    25. goodfriend(building);
    26. }
    27. int main()
    28. {
    29. test();
    30. }

    运行结果:

     可见goodfriend函数连private类型的属性都能够访问,因为加了如下代码使全局函数变成了友元函数:

    1. //让全局函数:好朋友函数 变成友元函数
    2. friend void goodfriend(Building* building);

    2. 整个类作友元类

    所谓的让整个类作为友元类,意思是让某个类成为另一个类的friend类

    1. #include
    2. #include
    3. using namespace std;
    4. //要在前面先加上这行代码,防止在goodfriend类中声明Building属性时报错
    5. class Building;
    6. class goodfriend {
    7. public:
    8. goodfriend();
    9. void visit();
    10. private:
    11. Building* building;
    12. };
    13. class Building {
    14. public:
    15. string m_room; //客厅
    16. Building()
    17. {
    18. this->m_Bedroom = "卧室";
    19. this->m_room = "客厅";
    20. }
    21. private:
    22. string m_Bedroom; //卧室
    23. };
    24. goodfriend::goodfriend()
    25. {
    26. building = new Building;
    27. }
    28. void goodfriend::visit()
    29. {
    30. cout << "好朋友正在访问" << this->building->m_room << endl;
    31. cout << "好朋友正在访问" << this->building->m_Bedroom << endl;
    32. }
    33. void test()
    34. {
    35. goodfriend gf;
    36. gf.visit();
    37. }
    38. int main()
    39. {
    40. test();
    41. }

    此时会报错,因为goodfriend类还不是building类的友元类

    加上以下添加友元类的代码即可:

    1. //让googfreind类作为Building类的友元类,语法如下:
    2. friend class goodfriend;

    完整代码:

    1. #include
    2. #include
    3. using namespace std;
    4. //要在前面先加上这行代码,防止在goodfriend类中声明Building属性时报错
    5. class Building;
    6. class goodfriend {
    7. public:
    8. goodfriend();
    9. void visit();
    10. private:
    11. Building* building;
    12. };
    13. class Building {
    14. //让googfreind类作为Building类的友元类,语法如下:
    15. friend class goodfriend;
    16. public:
    17. string m_room; //客厅
    18. Building()
    19. {
    20. this->m_Bedroom = "卧室";
    21. this->m_room = "客厅";
    22. }
    23. private:
    24. string m_Bedroom; //卧室
    25. };
    26. goodfriend::goodfriend()
    27. {
    28. building = new Building;
    29. }
    30. void goodfriend::visit()
    31. {
    32. cout << "好朋友正在访问" << this->building->m_room << endl;
    33. cout << "好朋友正在访问" << this->building->m_Bedroom << endl;
    34. }
    35. void test()
    36. {
    37. goodfriend gf;
    38. gf.visit();
    39. }
    40. int main()
    41. {
    42. test();
    43. }

     

        [友元类注意]

    1. 友元关系不能被继承
    2. 友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友
    3. 友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友

    3.成员函数作友元函数

            将成员函数定义为友元函数时一定要注意加上函数的定义域!

    1. #include
    2. #include
    3. using namespace std;
    4. class Building;
    5. class goodfriend {
    6. public:
    7. goodfriend();
    8. void visit();
    9. private:
    10. Building* building;
    11. };
    12. class Building {
    13. //将visit函数定义为Building类的友元函数,一定注意前面加函数的定义域goodfriend()
    14. friend void goodfriend::visit();
    15. public:
    16. string m_room; //客厅
    17. Building()
    18. {
    19. this->m_Bedroom = "卧室";
    20. this->m_room = "客厅";
    21. }
    22. private:
    23. string m_Bedroom; //卧室
    24. };
    25. goodfriend::goodfriend()
    26. {
    27. building = new Building;
    28. }
    29. void goodfriend::visit()
    30. {
    31. cout << "好朋友正在访问" << this->building->m_room << endl;
    32. cout << "好朋友正在访问" << this->building->m_Bedroom << endl;
    33. }
    34. void test()
    35. {
    36. goodfriend gf;
    37. gf.visit();
    38. }
    39. int main()
    40. {
    41. test();
    42. }

    运行结果:

     

  • 相关阅读:
    公路平竖曲线放样、坐标反算桩号GL.3-25PHF程序fx-5800p
    某音吸粉最快的10种方法
    C++ 实战Mongodb CRUD操作基本用法
    Django笔记三十之log日志记录详解
    弘辽科技:弘辽小编来和大家分享补单的三大技巧啦!
    Lua-http库写一个爬虫程序怎么样 ?
    【群智能算法】光学显微镜算法 OMA算法【Matlab代码#59】
    https相关内容
    数字音频处理--延时音效实现
    SpringMVC(四)REST风格
  • 原文地址:https://blog.csdn.net/qq_41583263/article/details/126643641