看这一段代码:
struct
显然是编译不过的,原因如题:
友元关系不能继承。
但考虑这么一个情景:
你想构建任意多的扩展去丰富B的功能,而这些扩展要用到B的一些非公开方法。
既然是非公开,那就得友元了,但是扩展的类名你又不知道。
最直观的想法就是建立一个扩展基类A,A是已知的,可以让A成为B的友元。
然后就遇到了上面的问题。
当然也不是没法解决。
既然A已经是B的友元,那只要在A里把B的方法给转发一下就好了,缺点就是要用到几个方法就得手动构造几个方法……
这不就是……
当然也有更简洁但更粗暴的做法:
struct
友元虽然不能继承,但继承可以继续友元啊,通过继承来获得扩展友元的能力。
在写扩展的地方,类名已经确定了,于是就可以达成目标。
事实上,我觉得public/protected/private + friend这种访问权管理是非常简陋的,有股浓浓的linux777权限管理的味道。
在大多数时候它都够用。但当你需要更精细的权限控制时,不足就很明显了。
教科书里的友元,通常是为了操作符重载。但实际用到友元的时候,通常是想暴露一些接口给一些特定的类。
可是友元就跟宏一样缺乏约束能力,还有向前声明的副作用,无形之中形成了一些语法上的坑。
如果不考虑向后兼容以及历史包袱的话,我觉得友元就该取消,转而用类似模板、concept的语法格式去实现友元,甚至是实现private、protected、public:
class
友元函数可能会比较难处理,但这么做至少让人感觉更统一了,功能也更强大了。
不过当private遇上继承,当访问权限遇上可见性,坑依旧存在。
XZiar:private vs publiczhuanlan.zhihu.com