[原创](Modern C++)现代C++的关键性概念: 什么是友元函数, 什么是友元类?
[作者]
常用网名: 猪头三
出生日期: 1981.XX.XX
企鹅交流: 643439947
个人网站: 80x86汇编小站
编程生涯: 2001年~至今[共24年]
职业生涯: 22年
开发语言: C/C++、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python
开发工具: Visual Studio、Delphi、XCode、Eclipse、C++ Builder
技能种类: 逆向 驱动 磁盘 文件
研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全/macOS应用软件安全
项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测
[序言]
在现代C++编程中, 封装性是面向对象设计的重要原则之一, 它确保类内部的数据和实现细节不被外部直接访问. 然而, 实际开发中有时会遇到特殊情况, 需要允许外部函数或类访问某个类的私有或保护成员. 此时, 友元机制便应运而生. 友元函数和友元类在提供必要访问权限的同时, 也可以在保持代码结构清晰的前提下, 实现更复杂或更高效的功能.
[什么是友元函数和友元类]
友元函数和友元类是一种特殊的访问授权机制, 允许外部函数或类访问某个类的私有(private)或保护(protected)成员. 它们提供了一种灵活的访问控制方式, 但打破了严格的封装规则.
[友元函数]
友元函数是一个非成员函数, 通过在类中用friend关键字声明, 它可以访问该类的私有和保护成员. 尽管不是类的成员函数, 但它拥有与成员函数类似的访问权限.
[友元类]
友元类是一个类, 通过在另一个类中用friend class声明, 该类的所有成员函数都可以访问被声明类的私有和保护成员. 友元类的所有成员函数都成为友元, 拥有完全的访问权限.
[代码演示]
下面的代码示例展示了如何使用友元函数和友元类. 类Point定义了两个私有成员变量mpr_int_X和mpr_int_Y, 并通过friend关键字分别声明了一个友元函数mpu_fun_GetSum()和一个友元类Point_Modify. 友元函数用于计算Point对象中X和Y的和, 而友元类中的成员函数mpu_pro_Modify()则能够修改Point对象的私有数据.
// 定义Point类, 表示一个二维坐标点
class Point
{
private:
// 私有成员, 分别表示X和Y坐标
int mpr_int_X, mpr_int_Y;
public:
// 自定义构造函数, 用于初始化坐标
Point(int int_param_X, int int_param_Y) :mpr_int_X{ int_param_X }, mpr_int_Y{ int_param_Y } {}
// 声明友元函数, 允许其访问Point类的所有成员
friend int mpu_fun_GetSum(const Point& class_param_p);
// 声明友元类, 允许该类的所有成员函数访问Point的私有成员
friend class Point_Modify;
};// End Point
// 定义友元类, 用于修改Point对象的私有成员
class Point_Modify
{
public:
// 成员函数, 修改传入Point对象的坐标值
void mpu_pro_Modify(Point& class_param_p)
{
class_param_p.mpr_int_X += 1;
class_param_p.mpr_int_Y += 1;
}// End mpu_pro_Modify()
};
// 定义友元函数, 用于计算Point对象中X和Y的和
int mpu_fun_GetSum(const Point& class_param_p)
{
return class_param_p.mpr_int_X + class_param_p.mpr_int_Y;
}// End mpu_fun_GetSum()
int main()
{
_setmode(_fileno(stdout), _O_WTEXT);
// 创建Point对象, 并使用友元函数mpu_fun_GetSum()读取私有成员
Point class_Point(1, 2);
std::wcout << L"X+Y: " << mpu_fun_GetSum(class_Point) << std::endl; // 输出 3
// 创建友元类对象, 并调用其成员函数mpu_pro_Modify()修改Point对象的私有数据
Point_Modify class_PointModify;
class_PointModify.mpu_pro_Modify(class_Point);
std::wcout << L"X+Y: " << mpu_fun_GetSum(class_Point) << std::endl; // 输出 5
std::cin.get();
return 0;
}
[代码说明]
1. 类的定义与构造
使用友元机制, Point类在内部声明了一个友元函数mpu_fun_GetSum和一个友元类Point_Modify.
2. 友元函数
mpu_fun_GetSum()虽然不是Point类的成员, 但通过友元声明, 可以直接访问mpr_int_X和mpr_int_Y, 实现对数据的读取并返回其和.
3. 友元类
Point_Modify类作为友元类, 其所有成员函数都可以访问Point的私有数据. 在代码中, mpu_pro_Modify()函数通过对Point对象的私有成员进行操作, 实现了对坐标值的修改.
[总结]
友元函数和友元类是C++中打破传统封装限制的有效手段, 在特定场景下提供了极大的灵活性和便利性. 优点: 能够直接访问类内部数据, 提高操作效率, 简化多个类之间的交互, 特别适用于关系密切的类设计. 缺点: 破坏了类的封装性, 可能导致数据安全问题, 不当使用可能降低代码的可维护性.