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;
}
友元类特点
-
友元关系单向:A 是 B 友元 ≠ B 是 A 友元
-
友元不继承:父类友元不会传给子类
-
不传递: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;
}
六、友元关键规则(考试必背)
-
friend声明在类内,不受 public/private 位置影响; -
友元不是类的成员函数,没有 this 指针;
-
友元可以访问类所有权限成员(private/protected/public);
-
友元关系单向、不继承、不传递;
-
运算符重载中,左操作数不是本类时,必须用友元;
-
尽量少用友元,会破坏封装性。
七、三种友元一句话区分
-
友元函数:全局函数做友元
-
友元类:整个类所有函数都有权访问
-
友元成员函数:只允许对方某一个成员函数访问