友元的目的是让一个函数或类,访问另一个类的私有成员
友元三种实现:全局函数做友元;类做友元;成员函数做友元
1.全局函数做友元
当全局函数想要访问类的私有成员时,需要将其声明为友元函数。示例如下:
class A{
private:
int n;
public:;
int m;
A()
{
n=10;
m=20;
cout<<"执行普通构造函数"<<endl;
}
~A()
{
cout<<"执行了析构函数"<<endl;
}
};
void test()
{
A a;
cout<<a.m<<endl;///可以访问
cout<<a.n<<endl;///不可以访问
}
示例中成员变量m是public,可以在类外访问;成员变量n是private,不可以在类外访问;此时全局函数test要想访问类A的私有成员,需要把函数变成友元函数。修改如下:
class A{
friend void test();
private:
int n;
public:;
int m;
A()
{
n=10;
m=20;
cout<<"执行普通构造函数"<<endl;
}
~A()
{
cout<<"执行了析构函数"<<endl;
}
};
void test()
{
A a;
cout<<a.m<<endl;///ok
cout<<a.n<<endl;///ok
}
2.类做友元
一个类想要访问另一个类的私有成员时,需要将当前类声明为友元类。示例如下:
class A{
private:
int n;
public:;
int m;
A()
{
n=10;
m=20;
cout<<"执行普通构造函数"<<endl;
}
~A()
{
cout<<"执行了析构函数"<<endl;
}
};
class B{
public:
B()
{
cout<<"B的构造函数"<<endl;
}
~B()
{
cout<<"B的析构函数"<<endl;
}
void test()
{
A a;
cout<<a.m<<endl;///OK
cout<<a.n<<endl;///error
}
};
类B的test函数中声明了类A的对象,但类A中成员变量m是public,成员变量n是private,无法访问;修改如下:
class A{
friend class B;
private:
int n;
public:;
int m;
A()
{
n=10;
m=20;
cout<<"执行普通构造函数"<<endl;
}
~A()
{
cout<<"执行了析构函数"<<endl;
}
};
class B{
public:
B()
{
cout<<"B的构造函数"<<endl;
}
~B()
{
cout<<"B的析构函数"<<endl;
}
void test()
{
A a;
cout<<a.m<<endl;///OK
cout<<a.n<<endl;///OK
}
};
在类A中把类B声明为友元类,此时类B中的任何地方都可以访问类A中的私有成员
3.成员函数做友元
在2中,类B中的任何位置都可以访问类A中的私有成员,如果只想test函数可以访问类A中的私有成员,则修改如下:
class B{
public:
B()
{
cout<<"B的构造函数"<<endl;
}
~B()
{
cout<<"B的析构函数"<<endl;
}
void test();
};
class A{
friend void B::test();
private:
int n;
public:;
int m;
A()
{
n=10;
m=20;
cout<<"执行普通构造函数"<<endl;
}
~A()
{
cout<<"执行了析构函数"<<endl;
}
};
void B::test()
{
A a;
cout<<a.m<<endl;///OK
cout<<a.n<<endl;///ok
}
这里需要注意类的顺序:把类B放在前面,且类B的友元函数放在类A的后面实现。