C++友元
C++ 友元
在 C++ 中,类的成员通常是私有的(private)或保护的(protected),只能被该类的成员函数或其派生类访问。但是有时候,我们希望让某些“外部”函数或类也能访问这些私有成员。这就用到了 C++ 的 friend 机制。
三种友元声明方式
| 类型 | 关键词声明方式 | 功能说明 |
|---|---|---|
| 友元函数 | friend void foo(Class c); |
函数可以访问类的私有/保护成员 |
| 友元类 | friend class ClassName; |
该类的所有成员函数都能访问私有成员 |
| 友元成员函数 | friend void ClassB::func(); |
指定类中某个函数作为友元函数 |
#include <iostream>
using namespace std;
class BankAccount {
private:
double balance;
public:
BankAccount() : balance(0.0) {}
void deposit(double amount) {
balance += amount;
}
// 声明友元函数
friend void showBalance(BankAccount acc);
// 声明友元类
friend class BankManager;
};
// 友元函数定义
void showBalance(BankAccount acc) {
cout << "Current balance: $" << acc.balance << endl;
}
// 友元类
class BankManager {
public:
void resetBalance(BankAccount& acc) {
acc.balance = 0; // 可以访问私有成员
cout << "Account reset to $0" << endl;
}
void grantBonus(BankAccount& acc, double bonus) {
acc.balance += bonus;
cout << "Granted bonus of $" << bonus << endl;
}
};
// 主函数
int main() {
BankAccount acc;
BankManager manager;
acc.deposit(100);
showBalance(acc); // 通过友元函数访问私有成员
manager.grantBonus(acc, 50); // 通过友元类访问私有成员
showBalance(acc);
manager.resetBalance(acc); // 友元类可以清空账户
showBalance(acc);
return 0;
}
-
友元关系是单向的:A 是 B 的友元,不代表 B 是 A 的友元。
-
友元关系不能继承:B 是 A 的友元,B 的子类不自动拥有权限。
-
友元关系不破坏封装:只是给某些特定函数或类授权访问私有成员,仍然保持良好的接口设计。
使用场景
| 使用场景 | 示例说明 |
|---|---|
| 运算符重载需要访问私有数据 | operator+ 通常作为友元函数实现 |
| 工具类需要访问另一个类的内部 | BankManager |
| 多个类之间协作,但不想开放接口 | 如两个类之间互为友元 |
| 调试输出、日志等需要访问内部结构 | 如 showBalance(BankAccount) |
友元的注意事项
- 滥用友元会破坏封装性,应慎重授权。
- 友元关系是写在被访问的类中,而不是写在友元的类或函数中。
- 如果一个函数或类要做友元,需要提前声明(前置声明)。
对比成员函数
class Box {
int width;
public:
Box(int w) : width(w) {}
void show(); // 成员函数
friend void print(Box b); // 友元函数
};
void Box::show() {
cout << "width = " << width << endl; // 直接访问
}
void print(Box b) {
cout << "width = " << b.width << endl; // 虽是外部函数,但是友元
}
| 对比点 | 成员函数 | 友元函数 |
|---|---|---|
| 是否属于类 | 是 | 不是 |
是否有 this |
有 | 没有 |
| 是否能访问私有成员 | 可以 | 可以(需要授权) |
| 调用方式 | 对象.函数() |
普通函数调用 函数(对象) |
| 常见用途 | 实现类的主要行为 | 运算符重载、跨类访问、调试等 |

浙公网安备 33010602011771号