友元函数
友元函数:是个函数。
三种访问权限:public,protected,private。
把函数成为类的友元函数,函数就能访问类的所有成员(成员变量,成员函数),忽视访问权限。
finend 函数定义放到类里,把函数生成成类的友元函数。
class Man : public Human //表示Men是Humen的子类
{
private:
void funcmen() const {
cout << "test" << endl;
}
friend void func(const Man& tempmen);//func成为了类的友元函数。
};//类结尾一定要分号
void func(const Man& tempmen) {
tempmen.funcmen();
}
Man men;
func(men);
总结:把函数生成成类的友元函数,函数就能访问类的所有成员,不受权限影响。
友元类
类可以把其他的类定义成友元类。
如果一个类是另一个类友元类,这个类在成员函数中访问另一个类的所有成员,不受访问权限影响。
让类A成为类C的友元类。可以先定义类A,后定义类C,编译器不会判断友元类是否存在,有的会检查,如果报错,在类前面加class 类名。
class C;//类C声明
class A {
private:
int data;
friend class C;//友元类的声明
};
class C
{
public:
void callCAF(int x, A& a)
{
a.data = x;
cout << a.data << endl;
}
};
注意每个类都负责控制自己的友元类和友元函数。
- 友元关系不能被继承,类C是类A的友元类,不是类A子类的友元类。
- 友元关系是单向的,类C是类A的友元类,类A不是类C的友元类。
- 友元关系没有传递性,类C是类A的友元,类C的子类不是类A 的友元类。
友元成员函数
友元类的权限太大,友元类所成员函数都能访问另一个类的所有成员。如果想只让类中一些函数访问另一个类的成员函数,可以定义友元成员函数。
这种函数不好写,必须注意代码结构,因为以后声明和定义的依赖关系。
- 只有类的public函数,才能成为其他类的友元函数。
- 有点:允许在特定情况下,某些非成员函数访问类的私有成员。是private更灵活
- 不足:破坏了类的封装性,降低了类的可靠性和维护性。
//A.h
#include "C.h"
//class C 类声明,用了callCAF函数,所以不行,要用include.
class A {
friend void C::callCAF(int x, A& a);//该函数是友元成员函数声明
private:
int data;
};
//C.h
class A;
class C
{
public:
void callCAF(int x, A& a);
};
//C.cpp
#include "C.h"
#include "A.h"
void C::callCAF(int x, A& a) {
a.data = x;
cout << a.data << endl;
}
//使用
C c;
A a;
c.callCAF(10, a);