C++第九篇:friend友元
1.友元的三个特点
- 单向性:A类中写了friend class B,说明B可以调用A中的函数,但过来不可以。
- 不可传递性:A类中写了friend class B,B类又写了friend class C,但C类并不能调用A类中的函数。
- 不可继承性:B类还有一个子类C,C类并不能算A类的友元,不可以调用A的函数。
2.友元函数
在 C++ 中,友元函数 是一种特殊的函数,它不属于某个类,但被允许访问该类的私有成员和保护成员,打破了类的封装性限制。
友元函数可以直接访问类中的保护成员和私有成员,直接看代码示例:
#include <iostream>using namespace std;class MyClass {
private:int x; int y;public:MyClass(int a, int b) : x(a), y(b) {}// 声明友元函数:该函数不是MyClass的成员,但可访问其私有成员friend int sum(MyClass obj);
};// 友元函数的实现(在类外,无需加类名和作用域运算符::)
int sum(MyClass obj) {//这里传引用更好MyClass& obj// 可以直接访问MyClass的私有成员x和yreturn obj.x + obj.y;
}int main() {MyClass obj(3, 5);cout << "sum : " << sum(obj) << endl; // 输出 sum : 8return 0;
}
运行结果:
示例中经过friend声明过后,sum函数就可以直接访问私有和保护成员,当然,前提是你得将对象当做参数传过来,因为友元函数不是类的成员,没有隐藏的this指针,只有通过这样才可以,使用引用更好。
3.友元成员函数
友元成员函数是指一个类的成员函数被另一个类声明为 “友元”,从而使得该成员函数能够访问另一个类的私有成员和保护成员。
代码如下:
#include <iostream>
using namespace std;// 声明类B,因为A的成员函数需要使用B
class B;// 定义类A
class A {
public:void printB(B* b);
};// 定义类B
class B {
private:int num = 100;// 声明A的成员函数printB为B的友元friend void A::printB(B* b);
};//友元函数的定义
void A::printB(B* b) {cout << "B的私有成员num:" << b->num << endl;
}int main() {A a;B b;a.printB(&b); // 输出:B的私有成员num:100return 0;
}
结果:
这里和前面的类型知识将函数改为了类的成员函数,注意声明友元函数是的写法即可。
4.友元类
如果类 A 声明类 B 为友元类,那么类 B 的所有成员函数都可以访问类 A 的私有和保护(成员,无需逐个声明函数。
看代码:
#include <iostream>
using namespace std;class A {
private:int secret; // 私有成员
public:A(int s) : secret(s) {}// 声明类B为友元类:B的所有成员函数可访问A的私有成员,// 但A的成员函数不能访问B的私有成员,具有单向性friend class B;
};class B {
public:void printSecret(A& a) {cout << "A的私有成员:" << a.secret << endl; }void modifySecret(A& a, int newVal) {a.secret = newVal; // 直接修改A的私有成员}
};int main() {A a(100);B b;b.printSecret(a); // 输出:A的私有成员:100b.modifySecret(a, 200);b.printSecret(a); // 输出:A的私有成员:200return 0;
}
结果如下:
这里只需要牢记友元类的特点就可以了。