友元函数

目录

友元

友元函数

友元类


友元

友元是C++中一种特殊的声明,允许其他类或函数访问另一个类的私有成员。通过友元的声明,可以实现代码的灵活性和效率。需要注意的是,友元是一种破坏封装性的机制,应当谨慎使用。在设计和使用类时,应尽量遵循封装的原则,只有在必要的情况下才使用友元。(友元关系是单向的,即如果类A声明类B为友元,那么类B并不自动将类A声明为友元。)

友元函数

问题:现在尝试去重载operator,然后发现没办法将operator重载成成员函数。因为cout的 输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作 数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以要将operator重载成 全局函数。但又会导致类外没办法访问成员,此时就需要友元来解决。operator>>同理。

class Date
 {
 public:
     Date(int year, int month, int day)
     :   _year(year)
     ,  _month(month)
     ,  _day(day)
 {}
// d1 << cout; -> d1.operator<<(&d1, cout);  不符合常规调用
// 因为成员函数第一个参数一定是隐藏的this,所以d1必须放在<<的左侧
ostream& operator<<(ostream& _cout)
 {
     _cout << _year << "-" << _month << "-" << _day << endl;
     return _cout;
  }
 private:
     int _year;

     int _month;

     int _day;
 };

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在 类的内部声明,声明时需要加friend关键字。

class Date
 {
     friend ostream& operator<<(ostream& _cout, const Date& d);
     friend istream& operator>>(istream& _cin, Date& d);
 public:
     Date(int year = 1900, int month = 1, int day = 1)
         : _year(year)
         , _month(month)
         , _day(day)
     {}
 private:
     int _year;
     int _month;
     int _day;
 };
 ostream& operator<<(ostream& _cout, const Date& d)
 {
     _cout << d._year << "-" << d._month << "-" << d._day;
     return _cout;   
}
 istream& operator>>(istream& _cin, Date& d)
 {
     _cin >> d._year;
     _cin >> d._month;
     _cin >> d._day;
     return _cin;
 }
 int main()
 {
     Date d;
     cin >> d;
     cout << d << endl;
     return 0;
}

友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

  • 友元关系是单向的,不具有交换性。          

        比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接 访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。

  • 友元关系不能传递

        如果C是B的友元, B是A的友元,则不能说明C时A的友元。

  • 友元关系不能继承。
    class Time
     {
         friend class Date;   
         // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
    public:
     Time(int hour = 0, int minute = 0, int second = 0)
         : _hour(hour)
         , _minute(minute)
         , _second(second)
         {}
     private:
         int _hour;
         int _minute;
         int _second;
     };
     class Date
     {
     public:
         Date(int year = 1900, int month = 1, int day = 1)
           : _year(year)
           , _month(month)
           ,_day(day)
           {}
     void SetTimeOfDate(int hour, int minute, int second)
       {
         // 直接访问时间类私有的成员变量
         _t._hour = hour;
         _t._minute = minute;
         _t._second = second;
       }
     private:
         int _year;
         int _month;
         int _day;
         Time _t;
     };

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值