欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > C++--static成员和友元

C++--static成员和友元

2024/10/24 18:16:12 来源:https://blog.csdn.net/m0_63703622/article/details/142025648  浏览:    关键词:C++--static成员和友元

1 static

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化

静态定义的成员变量在类外定义,变量类型 类名::变量名=value的形式。

此外,static还可以在类里面定义函数,这种static修饰的函数在外调用必须加域名才能使用,因为static修饰的函数不会隐含this指针。

2 友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多
用。
友元分为:友元函数和友元类

2.1 友元函数

通过实现重载operator<<去理解友元函数

在之前定义的日期类时,我们实例化日期对象然后去打印日期类的年月日定义了打印函数

我们可以这样去实现日期对象成员变量的值打印,但我们是否能利用重载实现通过cout<<的形式将的内容打印出来呢?

这时候我们就需要去定义一个重载函数operator<<。

这样我们就能在主函数去调用重载函数实现打印,其实d1.operator<<(cout)其实等价于d1<<cout。

但是,这样不是很方便也不符合我们常规写法,我们希望的写法是cout<<d1。

由于类里面定义的函数默认都有一个Data *this的指针参数,在外调用的时候都会将对象的地址传入,例如d1.operator(cout)==d1.operator(&d1,cout)。这个顺序是编译器默认的,不允许修改或者交换的,要达到cout<<d1的想法我们无法实现cout.operator<<(&d1),所以我们只能让它不为我们默认传入参数,我们自己定义传入参数,这时就需要用到static去实现。

所以我们的代码就变成了这样:

把函数定义在类外,不让编译器帮我我们默认添加一个Date*this的参数,并且我们自己加入Date*d,并且放到ostream&_cout的后面,但这时由于权限的问题,类外无法访问类内的成员变量,所以我们需要通过友元friend声明一下。

这样就能实现cout<<d1的效果了。

但这只能实现cout<<d1的效果,那如果想要实现cout<<d1<<d2<<endl的效果呢,这时就需要将函数稍微修改一下。

 

这样就能达到每次输出之和都会返回一个cout去输出下一个。

总结

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

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

说明:
友元函数可访问类的私有和保护成员,但不是类的成员函数
友元函数不能用const修饰
友元函数可以在类定义的任何地方声明,不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用原理相同

2.2 友元类

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

 

友元关系是单向的,不具有交换性。
比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
友元关系不能传递如果B是A的友元,C是B的友元,则不能说明C时A的友元。
友元关系不能继承。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com