简友广场想法C++学习笔记

第十一章 使用类(2)友元

2020-01-05  本文已影响0人  阿厉a_li

(二)友元

1.友元的概念

    友元有三种:友元函数友元类友元成员函数。这里主要介绍友元函数。通过让函数成为类的友元,可以赋予该函数与类的成员函数具有相同的访问权限。对于运算符重载,重载二元运算符(带有两个参数的运算符)的时候,常常需要友元,这是由于类当中重载的一般运算符都是左侧操作数是调用对象,右侧是调用的参数(可以为引用,变量等),当左右操作数互换的时候就会出现问题,因为左侧的操作数不一定是对象(也可能为基本类型的变量),此时就需要友元函数。大多数运算符都可以通过成员或非成员函数来重载非成员函数不是对象调用的,它使用的所有值,包括对象,都是显式参数。比如:Time operator*(double m,const Time & t);这是函数原型,A=2.75*B;A与B都是Time的对象,上面的乘法式子就相当于operator*(2.75,B)。

    对于非成员函数的运算符重载来说,运算符左边操作数相当于运算符函数的第一个参数,而右边的操作数相当于运算符函数的第二个参数。非成员函数可以解决上面运算符顺序问题,但是非成员函数不能直接访问类成员数据,因此设置了一类特殊的非成员函数可以用来访问类的私有数据,我们称为友元函数

2.创建友元

    将友元函数的原型放在类的声明当中,前面加上关键字friend。这个声明说明了两点:第一友元函数不是类的成员函数,不能用成员运算符(包括.号,->号)来调用它。第二,友元函数与成员函数的访问权限相同。另外要注意的是不要在友元函数的定义中使用关键字friend,也不要使用使用类的域限定符::,其实它就是一个普通的函数而已

    只有类声明才能决定哪个函数是友元函数,因此类声明仍然控制了哪些函数可以访问类的私有数据,所以,类方法和友元函数只是表达类接口的不同机制,并没有违反OOP原则。

    有时候可以直接反转运算符两边对象来使用类内运算符重载函数,此时可以不将这个函数设置成友元,但是将其设置成友元逻辑更清晰将作为类的接口),将来如果要直接访问类内私有成员的话只需要修改定义即可。因此,如果要为类重载运算符,并将非类对象作为第一个操作数,则可以用友元函数来反转操作数的顺序

3.常用的友元,<<运算符重载。

    运算符<<是ostream类重载的一个运算符,它有多种重载类型,因此ostream的对象cout可以用<<来输出所有的基本类型。要是cout来输出我们定义的类(比如Time)的对象,可以分成两个步骤来达成。第一步是让operator<<成为Time类的友元非成员函数,这样<<便可以调用Time类的私有成员用于输出。第二步是让operator<<的返回值为ostream对象的引用,比如cout的引用,这样就可以用<<来连续输出,就像用cout来输出基本类型,字符串,回车等一样。

    ostream的对象,常用的有cout,此外还有标准错误输出cerr,默认也是显示在屏幕上的。另外,ofstream的派生类ofstream的对象也是可以用ostream类的引用来指向的,这是类的继承的性质,因此,如果参数为ostream引用,那么可以将cout,cerr,ostream对象,ofstream对象传递给它。

上一篇 下一篇

猜你喜欢

热点阅读