在 C++ 中,友元函数(Friend Function) 是一种特殊的函数,它虽然不是某个类的成员函数,但被该类授权访问其私有(private)和保护(protected)成员。
为什么需要友元函数?
C++ 的核心特性之一是封装性:将数据(成员变量)和行为(成员函数)绑定在一起,并隐藏内部实现细节。
但有时,我们需要让非成员函数或其他类的成员函数访问某个类的私有成员,这时就可以使用 friend 关键字。
友元函数的基本语法
class MyClass {
private:
int secret;
public:
MyClass(int s) : secret(s) {}
// 声明友元函数
friend void displaySecret(const MyClass& obj);
};
// 友元函数的定义(不在类内部)
void displaySecret(const MyClass& obj) {
// 可以访问私有成员
std::cout << "Secret: " << obj.secret << std::endl;
}
int main() {
MyClass obj(42);
displaySecret(obj); // 输出: Secret: 42
return 0;
}
友元函数的特点
| 特点 | 说明 |
|---|---|
| 不是成员函数 | 友元函数在类外定义,没有 this 指针 |
| 可访问私有/保护成员 | 被 friend 声明后,可访问该类的所有私有和保护成员 |
| 破坏封装性 | 使用友元会削弱类的封装性,应谨慎使用 |
| 声明方式 | 在类内部用 friend 关键字声明,定义在类外 |
友元函数的常见用途
重载运算符(尤其是流插入/提取运算符)
#include <iostream>using namespace std;class Complex {private: double real, imag;public: Complex(double r = 0, double i = 0) : real(r), imag(i) {} // 友元函数用于重载 << 运算符 friend ostream& operator<<(ostream& os, const Complex& c);};ostream& operator<<(ostream& os, const Complex& c) { os << "(" << c.real << " + " << c.imag << "i)"; return os;}int main() { Complex c(3.0, 4.0); cout << c << endl; // 输出: (3 + 4i) return 0;}两个类之间共享私有数据
class B; // 前置声明
class A {
private:
int value;
public:
A(int v) : value(v) {}
// B 的成员函数可以访问 A 的私有成员
friend void B::showA(const A& a);
};
class B {
public:
void showA(const A& a) {
cout << "A's value: " << a.value << endl; // 合法
}
};
全局函数访问类的私有成员
class Box {
private:
double width;
public:
Box(double w) : width(w) {}
friend double getWidth(const Box& b);
};
double getWidth(const Box& b) {
return b.width; // 合法
}
友元函数 vs 成员函数
| 对比项 | 友元函数 | 成员函数 |
|---|---|---|
| 是否属于类 | 否 | 是 |
是否有 this 指针 |
无 | 有 |
| 访问权限 | 可访问私有/保护成员 | 可访问私有/保护成员 |
| 调用方式 | 普通函数调用 | 对象.函数() 或 对象->函数() |
| 封装性影响 | 削弱封装 | 保持封装 |
注意事项
- 谨慎使用:友元函数破坏了封装性,应仅在必要时使用。
- 不是继承的:友元关系不能继承。
- 可声明多个友元:一个类可以有多个友元函数或友元类。
- 友元类:除了友元函数,还可以将整个类声明为友元类(
friend class ClassName;)。
- 友元函数是 C++ 中一种打破封装的机制,允许非成员函数访问类的私有成员。
- 常见用途包括重载运算符、跨类数据共享等。
- 使用友元函数时应权衡封装性与便利性,避免滥用。
如有具体场景或代码问题,欢迎进一步提问!
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/484834.html



