1. 友元函数
1)友元函数是个函数,只要让普通函数func声明为类A的友元函数,那么func这个函数就能访问类A的所有成员(成员变量、成员函数),无论是public,private,protected
2)由于友元函数不属于类成员,所以友元函数的声明不受public、protected、private的影响
#include <iostream>
using namespace std;
class A
{
public:
int m_A = 5;
void A_func1()
{
cout << "A::A_func1()" << endl;
}
private:
int m_B = 10;
protected:
void A_func2()
{
cout << "A::A_func2()" << endl;
}
//声明友元函数,在public、protected、private下都可以声明
friend void func(A a); //声明void func(A a)为A的友元函数,使其可以访问A的所有成员变量、成员函数,包括public, private,protected
};
void func(A a)
{
cout << a.m_A << endl; //5, 普通函数可以访问A的public成员变量
a.A_func1(); //A::A_func1(), 普通函数可以访问A的public成员函数
cout << a.m_B << endl; //10, 将普通函数声明为友元函数后,可以访问A的所有成员,如private
a.A_func2(); //A::A_func2(), 将普通函数声明为友元函数后,可以访问A的所有成员,如protected
}
int main() {
A a;
func(a);
}
2. 友元类
1)可以在类A中把类B声明为类A的友元类,此时,可以在类B的成员函数中,访问类A的所有成员(成员变量、成员函数),无论是public,private,protected。
2)由于友元类不属于类成员,所以友元类的声明不受public、protected、private的影响。
#include <iostream>
using namespace std;
class B; //由于类A中用到了未定义的类B,因而需要提前声明
class A
{
public:
int m_A = 5;
void A_func1()
{
cout << "A::A_func1()" << endl;
}
private:
int m_B = 10;
protected:
void A_func2()
{
cout << "A::A_func2()" << endl;
}
//声明友元类,在public、protected、private下都可以声明
friend B; //声明B为A的友元类,使其可以访问A的所有成员变量、成员函数,包括public, private,protected
};
class B
{
public:
A a; //类B中存在A类对象
void B_func()
{
cout << a.m_A << endl; //5, 类B中可以访问类A的public成员变量
a.A_func1(); //A::A_func1(),类B中可以访问类A的private成员变量
cout << a.m_B << endl; //10,将类B声明为类A的友元类,此时类B中可以访问类A的所有成员,如private
a.A_func2(); //A::A_func2(),将类B声明为类A的友元类,此时类B中可以访问类A的所有成员,如protected
}
};
int main() {
B b;
b.B_func();
}
3. 友元成员函数
#include <iostream>
using namespace std;
class A; //由于类B中用到了未定义的类A,因而需要提前声明
class B
{
public:
void B_func(A &a); //由于类A未定义,因而此时只能声明类A的友元成员函数。
// 只有在类A定义后,才可定义该友元成员函数,毕竟它用于访问类A的成员
void B_func2(); //非A的友元,不可调用A的成员
};
class A
{
public:
int m_A = 5;
void A_func1()
{
cout << "A::A_func1()" << endl;
}
private:
int m_B = 10;
protected:
void A_func2()
{
cout << "A::A_func2()" << endl;
}
public:
//声明友元成员函数,在public、protected、private下都可以声明
//只有类B中的public成员函数,才可成为类A的友元函数
friend void B::B_func(A &a); //声明B的成员函数void B_func()为A的友元成员函数,使其可以访问A的所有成员变量、成员函数,包括public, private,protected
};
void B::B_func(A &a)
{
cout << a.m_A << endl; //5
a.A_func1(); //A::A_func1()
cout << a.m_B << endl; //10
a.A_func2(); // A::A_func2()
}
int main() {
A a;
B b;
b.B_func(a);
}
4. 友元的总结
1)友元类不能被继承。
2)友元关系是单向的,比如类B是类A的友元类,但并不表示类A是类B的友元类。
3)友元关系没有传递性,比如类B是类A的友元类,类C是类B的友元类,但并不代表类C是类A的友元类。
优点:使得访问protected、private更加灵活。
缺点:打破了类的封装性,降低了类的可靠性与可维护性。