• C++——友元(友元函数、友元类的特点)


    目录

    一、友元函数

    1、定义

    2、特点

    3、对友元函数定义理解: 

    4、对“友元是不能传递的”理解

     5、重载友元

    一、友元函数

    1、定义

    • (1)定义:友元函数是一个不属于类成员的函数,但它可以访问该类的私有成员。换句话说,友元函数被视为好像是该类的一个成员。
    • 友元函数可以是常规的独立函数,也可以是其他类的成员。实际上,整个类都可以声明为另一个类的友元。
    • 为了使一个函数或类成为另一个类的友元,必须由授予它访问权限的类来声明。类保留了它们的朋友的 "名单",只有名字出现在列表中的外部函数或类才被授予访问权限。通过将关键字 friend 放置在函数的原型之前,即可将函数声明为友元。
    • 理解:让函数或者类作为另外一个类的朋友,则可以访问当前类的private或protected。
    • (2)格式:
    • friend 返回类型 函数名 (参数列表);
    • 例:friend void Add(A& a);

    2、特点

    • (1)一个普通函数作为类的友元,那么在当前函数中就可以通过对象访问类的私有或者保护成员;
    • 注意:这个函数只能在外部定义,在当前类中引用即可。
    • (2)一个类的成员函数作为另外一个类的友元;
    • 注意:成员函数建议放在类外定义。
    • (3)一个类A作为另外一个类B的友元类,则A的所有成员函数就可以访问B的私有数据成员或保护成员;
    • 注意:
    •      ①友元是单向的;
    •      ②友元是不能进行传递的;
    •      ③友元是不能继承的。

    3、对友元函数定义理解: 

    1. class A {
    2. public:
    3. A(int i=0):m_i(i){}
    4. int GetI()const
    5. {
    6. return m_i;
    7. }
    8. protected:
    9. int m_j;
    10. friend void Add(A& a, A& b);//将Add函数作为类A的友元函数
    11. private:
    12. int m_i;
    13. };
    14. //想在当前Add函数中访问私有数据成员,又不想通过接口(公有函数)
    15. void Add(A& a, A& b)
    16. {
    17. cout << a.m_i << endl;
    18. cout << b.m_i << endl;
    19. cout << a.m_i<<"+" <"="<< a.m_i + b.m_i << endl;
    20. //cout << a.GetI() + b.GetI() << endl;
    21. }
    22. int main()
    23. {
    24. A a(5);
    25. A b(8);
    26. Add(a, b);
    27. }

    4、对“友元是不能传递的”理解

    //BB是AA的朋友,CC是BB的朋友,如果CC没有作为AA的友元类,则CC和AA没有关系——友元就不能传递

    1. //BB是AA的朋友,CC是BB的朋友,如果CC没有作为AA的友元类,则CC和AA没有关系——友元就不能传递
    2. class BB;
    3. class CC;
    4. class AA
    5. {
    6. public:
    7. friend class BB;
    8. private:
    9. int m_a;
    10. };
    11. class BB
    12. {
    13. public:
    14. friend class CC;
    15. void Show(AA& a);
    16. private:
    17. int m_b;
    18. };
    19. class CC
    20. {
    21. public:
    22. void print(BB& b);
    23. void test(AA& a);
    24. };
    25. void CC::test(AA& a)
    26. {
    27. cout << a.m_a << endl;//error,c不能访问a,类CC不是类AA的朋友
    28. }
    29. void BB::Show(AA& a)
    30. {
    31. cout << a.m_a << endl;
    32. }
    33. void CC::print(BB& b)
    34. {
    35. cout << b.m_b << endl;
    36. }

     5、重载友元

     cout——ostream类的对象
     cin——istream类的对象

    cout< 一般情况下:运算符可以解析成下面两种形式
    1、cout.<<(a)  ostream类中重载了<<,程序员不能修改
    2、<<(cout,a)  可以在程序员自己定义的类中将<<重载友元
    cout< cout< (cout<<(a)<

    friend ostream& operator<<(ostream &out,A &a)

    1. class A;//前项引用声明
    2. ostream& operator<<(ostream& out, A& a);
    3. class A
    4. {
    5. public:
    6. A(int i=0):m_i(i){}
    7. void print()
    8. {
    9. cout << m_i << endl;
    10. }
    11. A operator+(A& b)//this
    12. {
    13. return m_i + b.m_i;
    14. }
    15. friend A operator-(A& a, A& b);
    16. A operator++(int)//a++
    17. {
    18. int t = m_i;
    19. m_i = m_i + 1;
    20. return t;
    21. }
    22. friend A& operator++(A& a);
    23. friend ostream& operator<<(ostream& out, A& a);
    24. private:
    25. int m_i;
    26. };
    27. A& operator++(A& a)
    28. {
    29. ++a.m_i;
    30. return a;
    31. }
    32. A operator-(A& a,A&b)
    33. {
    34. return a.m_i + b.m_i;
    35. }
    36. //cout<
    37. ostream& operator<<(ostream& out, A& a)
    38. {
    39. out << a.m_i;
    40. return out;
    41. }

    如有错误,敬请指正。

    您的收藏与点赞都是对我最大的鼓励和支持!

  • 相关阅读:
    2022年秋招java后端面试总结,只看这一篇文章就够了
    js常用的数组处理方法
    go zero手把手教你入门案例
    VBA 浏览文件夹对话框调用的几种方法
    React Hook - 自定义Hook的基本使用和案例练习
    编程陷阱:切片追加
    蓝桥杯备战刷题three(自用)
    openpnp - 接入西门子二手飞达
    支付宝支付
    JavaScript 数据结构与刷题基础
  • 原文地址:https://blog.csdn.net/x20020402/article/details/127539849