C++ 笔记 友元(面向对象)

C++ 笔记(面向对象):友元

在 C++ 面向对象的封装特性中,类会将私有成员(private)和保护成员(protected)隐藏起来,仅允许类自身的成员函数访问 。但在实际开发中,我们有时需要让外部的函数或其他类 ,直接访问一个类的非公有成员 ------ 这就是友元(friend) 的作用。

友元是 C++ 提供的一种突破封装的机制,它允许外部函数或类访问另一个类的私有 / 保护成员。本文将从概念、分类、用法、优缺点四个维度,全面讲解友元的使用。

一、友元基础概念

1. 核心定义

友元 :使用 friend 关键字声明的外部函数外部类,可以直接访问当前类的所有成员(包括 private、protected)。

2. 核心特点

友元不是类的成员,只是被类 "授权" 的外部对象;

友元可以是普通全局函数 ,也可以是其他类的成员函数 ,甚至是整个类

友元单向性:A 是 B 的友元,≠ B 是 A 的友元;

友元不传递:A 是 B 的友元,B 是 C 的友元,≠ A 是 C 的友元。

3. 友元的作用场景

让两个关联类高效共享数据;

重载运算符时(如 <<>>),需要访问类的私有成员;

让工具函数直接操作类的内部数据,提升效率。

二、友元的三种分类

友元分为三类:友元全局函数友元成员函数友元类

1. 友元全局函数

普通全局函数声明为某个类的友元,该函数可直接访问类的私有成员。

代码示例
cpp 复制代码
#include <iostream>
using namespace std;

class Person {
    // 声明全局函数 showAge 为 Person 类的友元
    friend void showAge(Person& p);

private:
    int age = 20; // 私有成员
};

// 友元全局函数:可以直接访问 Person 的私有成员 age
void showAge(Person& p) {
    cout << "年龄:" << p.age << endl;
}

int main() {
    Person p;
    showAge(p); // 调用友元函数
    return 0;
}
关键点

友元声明写在类内部任意位置(public/protected/private 都可以);

函数本身是全局函数,不属于类。

2. 友元成员函数

另一个类的成员函数声明为友元,该成员函数可访问当前类的私有成员。

代码示例
cpp 复制代码
#include <iostream>
using namespace std;

// 提前声明 Person 类
class Person;

class Student {
public:
    // 声明为 Person 的友元成员函数
    void showPersonAge(Person& p);
};

class Person {
    // 声明 Student 的 showPersonAge 为友元
    friend void Student::showPersonAge(Person& p);

private:
    int age = 22;
};

// 实现友元成员函数
void Student::showPersonAge(Person& p) {
    cout << "Person的年龄:" << p.age << endl;
}

int main() {
    Person p;
    Student s;
    s.showPersonAge(p);
    return 0;
}
关键点

必须提前声明类,否则编译器无法识别;

只有这一个成员函数有权限,不是整个类。

3. 友元类

整个类 声明为友元,该类的所有成员函数都可以访问当前类的私有成员。

代码示例
cpp 复制代码
#include <iostream>
using namespace std;

class Person {
    // 声明 Student 整个类为友元
    friend class Student;

private:
    int age = 23;
    string name = "小明";
};

class Student {
public:
    // 可以访问 Person 所有私有成员
    void show(Person& p) {
        cout << "姓名:" << p.name << endl;
        cout << "年龄:" << p.age << endl;
    }
};

int main() {
    Person p;
    Student s;
    s.show(p);
    return 0;
}
关键点
  • 友元类的所有成员函数都能访问私有成员;
  • 写法:friend class 类名;

三、友元的优缺点

优点

  1. 灵活方便:快速实现外部访问私有成员;
  2. 效率更高:避免频繁调用公有接口函数;
  3. 适配运算符重载 :如 cout << 对象 必须用友元。

缺点

  1. 破坏封装性:类的私有成员不再安全;
  2. 降低代码可维护性:外部代码可直接修改内部数据;
  3. 耦合度变高:类与类、类与函数关联性太强。

四、使用建议

  1. 能不用就不用:优先用公有成员函数访问;
  2. 必须用时再用:运算符重载、紧密关联的类;
  3. 最小权限原则 :优先用友元函数 ,少用友元类

总结

  1. 友元friend 声明的外部函数 / 类,可访问类的私有成员;
  2. 三类友元:友元全局函数友元成员函数友元类
  3. 特点:单向、不传递、不是类成员
  4. 优点:灵活高效;缺点:破坏封装,谨慎使用。
相关推荐
TT_44192 小时前
python程序实现图片截图溯源功能
开发语言·python
笨笨饿2 小时前
20_Git 仓库使用手册 - 初学者指南
c语言·开发语言·嵌入式硬件·mcu·学习
人间打气筒(Ada)2 小时前
go实战案例:如何通过 Service Meh 实现熔断和限流
java·开发语言·golang·web·istio·service mesh·熔断限流
C++ 老炮儿的技术栈2 小时前
分享一个安全的CString
c语言·c++·windows·git·安全·visual studio
cqbelt2 小时前
Python 并发编程实战学习笔记
笔记·python·学习
桦03 小时前
[C++复习]:STL
开发语言·c++
前端小咸鱼一条3 小时前
16.迭代器 和 生成器
开发语言·前端·javascript
小陈工3 小时前
2026年3月31日技术资讯洞察:AI智能体安全、异步编程突破与Python运行时演进
开发语言·jvm·数据库·人工智能·python·安全·oracle
苏宸啊4 小时前
rbtree封装map和set
c++