C++:成员友元函数(成员函数友元化)
友元函数
友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。
友元函数既可以是不属于任何类的非成员函数(全局函数),也可以是另一个类的成员函数(友元化时函数名前要加上所属的类),本文主要讨论一个类的成员函数如何成为另一个类的友元函数
具体实现
# include <iostream>
# include <string>
using namespace std;
class Student;//对Student类的提前引用声明
class Teacher
{
private:
int num;
string name;
string sex;
public:
Teacher(int n, string na, string s) { num = n; name = na; sex = s; }
//如果之前没有对对Student类做提前引用声明,底下就会报错无法识别Student类
void transform(Student& b);
Teacher(){};
void display()
{
cout << "TEACHER:" << endl;
cout << num << endl;
cout << name << endl;
cout << sex << endl;
}
};
class Student
{
public:
Student(int n, string na, string s):num(n), name(na), sex(s) {};
void display()
{
cout << "student:" << endl;
cout << num << endl;
cout << name << endl;
cout << sex << endl;
}
friend void Teacher::transform(Student& b);
private:
int num;
string name;
string sex;
};
//transform函数的具体定义一定要写在Student类完整定义之后,否则函数中对类中成员的使用会报错
void Teacher::transform(Student& b)
{
num=b.num;
name=b.name;
sex=b.sex;
}
int main()
{
Student t(12, "玛奇玛", "女");
t.display();
Teacher s;
s.transform(t);
cout<<"转换后:"<<endl;
s.display();
return 0;
}
运行结果:

说明
提前引用声明注意事项
我们知道C++的类应当是先定义,然后使用。但在处理相对复杂的问题、考虑类的组合时,很可能遇到俩个类相互引用的情况,这种情况称为循环依赖。(列如头文件互引)
这里类Teacher的公有成员函数transform的形参是类Student的对象,同时类Student的友元函数也属于Teacher类。由于在使用一个类之前,必须首先定义该类,因此无论将哪一个类的定义放在前面,都会引起编译错误。结局这个问题的方法,就是使用前向引用声明。前向引用声明,是在引用未定义的类之前,将该类的名字告诉编译器,编译器知道那是一个类名。这样,当程序中使用这个类名时,编译器就不会认为是错误,而类的完整定义可以在程序的其他地方。在上述程序加上下面的前向引用声明,问题就解决了。
使用前向引用声明虽然可以解决一些问题,但它并不是万能的。需要注意的是,尽管使用了前向引用声明, 但是在提供一个完整的类定义之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象(及类中的成员),上述案例中就是在Student类完整定义之后再定义Teacher类的成员函数transform,另一个案例如下
class Fred; //前向引用声明
class Barney
{
Fred x; //错误:类Fred的声明尚不完善
};
class Fred
{
Barney y;
};
编译出错的原因是对此类Fred的前向引用声明只能说明Fred是一个类名,而不能给出该类的完整定义,因此在类Barney中不能定义或使用类Fred的数据成员。
应该记住:当你使用前向引用声明时,你只能使用被声明的符号,而不能涉及类的任何细节。
C++的类可以进行前向声明。但是,仅仅进行前向声明而没有定义的类是不完整的,这样的类, 只能用于定义指针、引用、以及用于函数形参的指针和引用。
而不能定义对象(因为此时编译器只知道这是个类,还不知道这个类的大小有多大),也不能访问类的对象,任何形式的访问都不允许(因为此时根本不知道有些什么成员)。等到类正式定义以后,就可以以各种方式使用该类了。
参考:
https://blog.youkuaiyun.com/weixin_30604651/article/details/98868240
https://blog.youkuaiyun.com/weixin_30800807/article/details/95889531
本文详细讲解了C++中如何使一个类的成员函数成为另一个类的友元函数,包括如何避免循环依赖问题,前向引用声明的应用,以及友元化过程中的注意事项。通过实例演示了友元函数的使用及其限制。
489





