【C++】使用友元/内部类时常见的问题(总结)

友元函数的总结

我在之前的博客friend友元和内部类 中讲到了友元类/函数和内部类的使用细节,有需要的可以查看博客内容。这里我主要介绍一下,在使用友元类和内部类时要注意的一些问题。
我总结了主要的几个知识点:
1)C++引用友元函数是为该类提供一个(除自己以外)的访问窗口。
2)这个友元函数并不是该类的成员函数,它是一个定义在类外的普通函数,只是在类中声明该函数可以直接访问类中的private和protected成员。故调用也与普通函数一样,不用通过对象引用。。
3)友元函数声明在类的public和private都一样,但是要在类外实现,不用加类限定,也不能用const修饰。
4)一个类的成员函数可以是另一个类的友元函数。一个函数也可以是多个类的友元函数,只要在各自类内声明即可。
5)友元函数没有this指针,故参数如果是类的非static成员时必须用对象做参数。
6)内部类其实是外部类的友元类。

下面有几个常见的问题和误区:

1.友元类和内部类的联系和区别
  • 下面我将含有友元类/内部类的类暂称 “完整类”,完整类去掉友元类/内部类暂称“主类”,这里名字只用作区分

我们一直说内部类其实是外部类的友元类。所以内部类和友元类有以下共同点

  1. sizeof(完整类)=size(主类),即友元类和内部类在sizeof计算中都不算入大小
  2. 内部类和友元类的可生效位置是一样的,无论声明在类的public,protected,private都可以。
  3. 友元类/内部类也是独立的一个类,他们与完整类有关联但并不属于完整类,所以完整类无法使用自己的对象去访问友元类/内部类的成员。

但内部类与友元类也不完全相同, 两者的区别主要有两点:

  1. 访问完整类的成员方式不同。友元类在访问完整类中的成员时需要通过对象名(static成员除外),而如果是内部类就可以直接访问其完整类中的类成员。
  2. 两者实现的位置不同。友元类实现在完整类的外部(声明在内部),内部类实现在完整类的内部。
2.友元函数访问类对象中的成员时,都必须通过对象名.成员访问

说法错误!只有非static成员才需要通过对象访问

类的友元函数中没有this指针,所以在访问类对象中的非static成员时,必须通过对象名找到
但是友元函数在访问类对象中的static成员时,可以直接访问,无需通过对象访问。

3.友元函数重载运算符时可以无参数实现

说法错误!友元函数无this指针,若无参数则无法运算

友元函数中无this指针,所以我们给友元函数传几个参数,它就有几个参数。
那么对于运算符的重载,若传一个参数则是单目运算符,若传两个参数则是双目运算符,但若无参数就是无运算,此时重载会发生错误。

4.输出<< 可以重载为非成员函数

说法正确!为了符合使用习惯,我推荐使用友元函数重载<<

首先我重载operator<< 需要用到对象的成员,这时我就会想到把它重载为成员函数,可以直接访问对象成员。在friend友元和内部类我也讲到,重载为成员函数是可行的,但是在成员函数中this指针必占第一个参数的位置,所以我调用的方法是a.operator<<(cout) ;或者 a << cout;
而我们习惯性使用cout<<a;即希望输出对象写在运算符的后面。这个时候友元函数的作用就充分体现了,它没有this指针,参数的位置可以由自己决定,最符合我们使用习惯。所以我推荐把<<重载为友元函数。
示例:ostream & operator<<(ostream& _cout, const A& a) //通过友元函数重载<<,并规定使用规则
{ _cout << a._a; return _cout;}

以上是使用友元函数/内部类时常见的问题,最后还想强调, 友元函数没有this指针!友元函数没有this指针!友元函数没有this指针! 重要的事情说三遍。有遇到其他的问题,我会及时更新的,大家可以先关注小编哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值