关键字 friend 允许特定的函数或其他类访问声明 friend 的类的私有和保护成员。Friend 函数可以是全局的,也可以是其他类的方法。这种构造使得需要访问类内部状态的函数能够实现,但这些函数在逻辑上与该类的接口并不相关。
建议在以下情况下使用 friend:
注意:
示例:
class Box { int width; public: Box(int w): width(w) {} friend void printWidth(const Box &b); }; void printWidth(const Box &b) { std::cout << b.width << std::endl; }
问题: friend 函数可以是虚拟的吗?
常见回答: 是的,因为 friend 是函数的修饰符。
正确回答: 不,friend 函数不能是虚拟的,因为它们不是类的成员!
示例:
class Example { friend virtual void foo(); // 编译错误: virtual 不能应用于 friend };
故事: 在设计矩阵库时,所有的算术运算符都被设为 friend 函数以加快速度,但忘记了支持常量性,过度开放了对私有成员的访问。后来出现了问题——项目中的其他函数无意中改变了 Matrix 的内部状态。
故事: 在企业系统中,助手类之间相互成为 friend 以共享对私有成员的访问。这导致了循环依赖——增加新特性需要修改所有相关类。随后的重构花费了数周时间。
故事: 为了进行封闭测试,决定将测试类设置为 production 类的 friend。当出现多个单元测试集时,跟踪哪些私有方法实际上被使用变得不可能——测试开始依赖于内部实现,这导致代码维护变得复杂。