05 友元

友元

概念

友元可以访问与其有好友关系的类中的成员。

友元提供不同类的成员函数之间类的成员函数与一般函数之间进行数据共享的机制。

实际是对封装的破坏

友元既可以是不属于任何类的一般函数,也可以是另一个类的成员函数,还可以是整个的

包括:

  • 友元函数

    • 不是当前类的成员函数,而是独立于当前类的外部函数

    • 可以访问该类的所有对象的成员,包括私有、保护、公有成员

    • 声明:

      • 位置:类体中
      • 格式:函数名前加friend
    • 定义:

      • 类体内:函数名前加friend

        • Example 1. 在类内定义友元函数

          image-20211118182246315
      • 类体外:同一般函数(函数名前不能类名::,因为友元函数不是类的成员函数)

        • Example 2. 在类外定义友元函数

          image-20211118182443813
      • 不是类所独有,尽量定义在类体外

      • Example 3. 友元函数在多个类中

        #include <iostream>
        #include <string.h>
        using namespace std;
        class boy;
        class girl
        {
        private:
            char name[25];
            int age;
        
        public:
            girl(char N[], int a)
            {
                age = a;
                strcpy(name, N);
            }
            friend void prdata(const girl plg, const boy plb);	//in class girl
        };
        class boy
        {
        private:
            char name[25];
            int age;
        
        public:
            boy(char N[], int a)
            {
                age = a;
                strcpy(name, N);
            }
            friend void prdata(const girl plg, const boy plb);	//in class boy
        };
        void prdata(const girl plg, const boy plb)	//definition
        {
            cout << "name:" << plg.name << endl
                 << "age:" << plg.age << endl
                 << "name:" << plb.name << endl
                 << "age:" << plb.age << endl;
        };
        int main()
        {
            girl g1("Zhang Hao", 12),
                g2("Li Ying", 13),
                g3("Wan Hong", 16);
            boy b1("Chen Lin", 14),
                b2("Wang Hua", 13),
                b3("Bai xun", 16);
            prdata(g1, b1);
            prdata(g2, b2);
            prdata(g3, b3);
            return 0;
        }
        /*
        name:Zhang Hao
        age:12
        name:Chen Lin
        age:14
        name:Li Ying
        age:13
        name:Wang Hua
        age:13
        name:Wan Hong
        age:16
        name:Bai xun
        age:16
        */
        
    • 友元函数没有this指针,通过入口参数(该类对象)来访问对象的成员

  • 友元成员

    • 友元函数可以是一般函数(非成员函数),也可以是另一个类中的成员函数

    • 一个类的成员函数也可以作为另一个类的友元,指针成员函数不仅可以访问自己所在类对象中的所有成员,还可以访问friend声明语句所在类对象中的所有成员

    • 以上两条其实本质是一致的,都是友元成员

      • 一个类的成员函数作为另一个类的友元函数时,必须先定义这个类
    • Example 4

      #include <iostream>
      using namespace std;
      class Date;
      class Time
      {
      public:
          Time(int h, int m, int s)
          {
              hour = h, minute = m, sec = s;
          }
          void display(Date &);
      
      private:
          int hour, minute, sec;
      };
      class Date
      {
      public:
          Date(int m, int d, int y)
          {
              month = m, day = d, year = y;
          }
          friend void Time::display(Date &);
              //友元函数在Date类中是,是Time类的成员函数
      
      private:
          int month, day, year;
      };
      void Time::display(Date &d)
      {
          cout << d.month << "/" << d.day << "/" << d.year << endl;
          cout << hour << ":" << minute << ":" << sec << endl;
      }
      int main()
      {
          Time t1(10, 13, 56);
          Date d1(12, 25, 2004);
          t1.display(d1);
          return 0;
      }
      /*
      12/25/2004
      10:13:56
      */
      
  • 友元类

    • Example 4. 友元类

      class CCar
      {
      private:
          int price;
          friend class CDriver;  //声明 CDriver 为友元类
      };
      class CDriver
      {
      public:
          CCar myCar;
          void ModifyCar()  //改装汽车
          {
              myCar.price += 1000;
              //因CDriver是CCar的友元类,故此处可以访问CCar的私有成员
          }
      };
      
    • 如上Example中,CDriver类中所有的成员函数都是CCar类的友元函数

    • 友元的关系是单向的,不是双向的

      • X类是Y类的友元,类Y不一定是类X的友元
    • 友元关系不能传递

      • X类是Y类的友元,Y类是Z类的友元,X类不一定是类Z的友元
    • 实际应用中,除非确有必要,一般不把整个类声明为友元类,而只将确实有需要的成员函数声明为友元函数,这样更安全

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值