C++ 知识点17 友元

C++ 友元(friend)


一、友元是什么

友元 :用 friend 关键字,让外部函数 / 其他类

可以直接访问本类的 private、protected 私有成员。

核心:

  • 破坏封装,但能简化运算符重载、跨类访问

  • 友元不是类的成员,没有 this 指针


二、友元函数(全局函数做友元)

语法

类里面声明:

cpp 复制代码
friend 返回值 函数名(参数);

完整代码示例

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
​
class Person
{
    // 私有成员
    string name;
    int age;
​
    // 声明全局函数为友元
    friend void showPerson(const Person& p);
​
public:
    Person(string n, int a) : name(n), age(a) {}
};
​
// 全局普通函数
void showPerson(const Person& p)
{
    // 是友元,直接访问 private 成员
    cout << "姓名:" << p.name << " 年龄:" << p.age << endl;
}
​
int main()
{
    Person p("张三", 18);
    showPerson(p);
    return 0;
}

输出:

cpp 复制代码
姓名:张三 年龄:18

重点:

  • showPerson 不是类成员,是全局函数

  • 因为加了 friend,能直接读私有成员


三、用友元重载运算符(必考)

前面讲运算符重载时:

左操作数不是本类对象,必须用友元重载。

示例:重载 +,实现 int + 对象

cpp 复制代码
#include <iostream>
using namespace std;
​
class Point
{
private:
    int x, y;
public:
    Point(int a = 0, int b = 0) : x(a), y(b) {}
​
    // 声明友元运算符重载
    friend Point operator+(int num, const Point& p);
    friend void print(const Point& p);
};
​
// 全局实现
Point operator+(int num, const Point& p)
{
    return Point(num + p.x, num + p.y);
}
​
void print(const Point& p)
{
    cout << p.x << " , " << p.y << endl;
}
​
int main()
{
    Point p(10, 20);
    Point res = 5 + p;   // 左操作数是int,只能用友元
    print(res);
    return 0;
}

四、友元类(整个类做友元)

语法:

cpp 复制代码
friend class 类名;

含义:

  • B 是 A 的友元类

  • B 的所有成员函数都可以访问 A 的私有成员

代码演示

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
​
// 前置声明
class Person;
​
// 教师类
class Teacher
{
public:
    void getInfo(Person& p);
};
​
class Person
{
private:
    string name = "李四";
    int age = 20;
​
    // 声明 Teacher 为友元类
    friend class Teacher;
};
​
void Teacher::getInfo(Person& p)
{
    // 友元类,直接访问私有
    cout << p.name << " " << p.age << endl;
}
​
int main()
{
    Person p;
    Teacher t;
    t.getInfo(p);
    return 0;
}

友元类特点

  1. 友元关系单向:A 是 B 友元 ≠ B 是 A 友元

  2. 友元不继承:父类友元不会传给子类

  3. 不传递:A 友元 B,B 友元 C ≠ A 友元 C


五、友元成员函数(只让对方一个成员函数做友元)

只指定另一个类里的某一个函数为本类友元,不是整个类。

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
​
// 前置声明
class Student;
​
class School
{
public:
    void showStu(Student& s);
};
​
class Student
{
private:
    string id = "2026001";
​
    // 只把 School::showStu 设为友元
    friend void School::showStu(Student& s);
};
​
void School::showStu(Student& s)
{
    cout << "学号:" << s.id << endl;
}
​
int main()
{
    Student s;
    School sc;
    sc.showStu(s);
    return 0;
}

六、友元关键规则(考试必背)

  1. friend 声明在类内,不受 public/private 位置影响;

  2. 友元不是类的成员函数,没有 this 指针;

  3. 友元可以访问类所有权限成员(private/protected/public);

  4. 友元关系单向、不继承、不传递;

  5. 运算符重载中,左操作数不是本类时,必须用友元;

  6. 尽量少用友元,会破坏封装性。


七、三种友元一句话区分

  1. 友元函数:全局函数做友元

  2. 友元类:整个类所有函数都有权访问

  3. 友元成员函数:只允许对方某一个成员函数访问

相关推荐
Ai-_Man3 分钟前
Coze扣子还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·1024程序员节
UIU11410 分钟前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯
raindayinrain11 分钟前
c++设计模式
开发语言·c++·设计模式
旖旎夜光14 分钟前
LeetCode 315: 算右侧小于当前元素的个数(归并排序) —— 题解
c++·学习·算法·leetcode·排序算法
hiahiahia12320 分钟前
Streaming Model Output
开发语言·前端
像风一样自由202023 分钟前
2.如何用FastAPI把一个Python算法封装成HTTP服务
python·算法·fastapi
D e re k ZH28 分钟前
保序回归:从 PAVA 到可并堆的单调约束优化
c++·算法·数据挖掘·回归·kotlin
青少儿编程课堂29 分钟前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:字典树前缀树与单词检索统计
c++·python·算法·bfs·信息学竞赛
Nuanyt33 分钟前
LeetCode Hot 100 链表专题2 3 题 (Java)
java·笔记·算法·leetcode·链表
熊猫钓鱼>_>1 小时前
鸿蒙PC高分屏与键鼠交互适配:DPI缩放、右键菜单一次讲清
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙·鸿蒙心迹