C++笔记(面向对象)友元
友元分为外部函数友元 成员函数友元 类友元
友元函数
用关键字friend声明一个函数为类的友元函数,从而使该函数可以访问类的所有成员(主要可以访问类的私有成员
class Student {
private:string name;int score;
public:Student(string n, int s) : name(n), score(s) {}// 声明友元函数friend void showSecret(const Student& s);
};
// 友元函数定义(不是成员函数!)
void showSecret(const Student& s) {// 可以直接访问私有成员!cout << "姓名:" << s.name << ", 分数:" << s.score << endl;
}
注意:
它是非成员函数 (无this指针)
所以它不能被继承
友元破坏了封装性
友元函数不能被继承
成员函数和友元函数的区别
访问权限
- 成员函数:因为是类的 “内部函数”,所以可以直接访问所属类的所有成员(包括私有、保护、公有成员)。
- 友元函数:作为 “外部特殊权限函数”,只能访问 “声明它为友元的那个类” 的私有和保护成员(不是能访问所有类的私有成员,是针对性的某一个类)。
调用方式
- 成员函数:调用时要通过类的对象(或指针、引用),形式为 obj.func()(对象调用)、p->func()(指针调用)等,本质是依托类的实例来调用。
- 友元函数:它本质是普通的全局函数或其他类的成员函数(只是被某类赋予了访问私有成员的权限),所以调用时像普通函数一样,把类对象当作参数传递,形式为 func(obj)。
友元函数与访问权限关键字的关系
类中的访问权限关键字(public、private、protected)是用来限制类 ** 成员(变量、函数)** 的访问范围的。但友元函数不受这些关键字限制,不管把友元函数的声明放在类的公有、私有还是保护部分,它都能正常访问类的所有成员,效果是一样的。这也体现了友元 “打破常规访问限制” 的特点。
友元函数的作用域
友元函数的作用域不是它所友元的那个类的作用域。
如果友元函数是另一个类的成员函数,那它的作用域就属于那个 “另一个类” 的作用域;
如果友元函数是普通的全局函数,那它的作用域就和一般全局函数一样(全局作用域)。
友元类
声明某个类为另一个类的友元,友元类中每个成员函数都可以访问另一个类的所有成员
若b是a的友元类,那么b必须在a之前声明或定义,也就是也需要提前声明
不具有对称性:A 是 B 的友元,并不意味着 B 是 A 的友元。
不具有传递性:A 是 B 的友元,B 是 C 的友元,但 A 不是 C 的友元。
不具有继承性:Base 类型继承 Object 类型,如果 Object 类型是 A 的友元,但 Base 类型不是 A 的友元。
