C++中的友元函数
友元函数可以访问类中的私有变量,类似静态函数,友元函数不受public private protected等修饰符的限制,可以放在类中的任意位置。
如果在类的声明中定义友元函数(即友元函数的声明和定义放在一处,都在类内部),则此友元函数为内联函数,即使没有使用inline关键字,且此友元函数的作用域为文件范围,而非类范围,调用此友元函数时也无需带“类名::”,虽然此友元函数的定义声明都在类内部。只要包含这个类所在的头文件,就可以调用友元函数,另外友元函数定义和声明分开时,只需在类内部声明一次即可,无需在类外部再次声明。
下面我们使用普通友元函数,内联友元函数,和静态成员函数,来实现打印Student类中的私有成员变量的功能
test2.h文件
#ifndef _TEST2_H_
#define _TEST2_H_
#include <string>
using namespace std;
class Student
{
private:
string name;
int stu_nu;
//此处已经算是友元函数的声明,无需在类外部再次声明,且不受private修饰符限制
friend void show(const Student & stu);
public:
Student(string name, int stu_nu);
//print函数为内联函数,虽然没有使用inline关键字
friend void print(const Student & stu)
{
cout << "name is" << stu.name << endl;
cout << "stu number is " << stu.stu_nu << endl;
}
//使用类的静态成员函数实现同样的功能
static void print_static (const Student &stu)
{
cout << "name is" << stu.name << endl;
cout << "stu number is " << stu.stu_nu << endl;
}
};
#endif
show.cpp文件
#include <iostream>
#include "test2.h"
using namespace std;
void show(const Student & stu)
{
cout << "name is " << stu.name << endl;
cout << "stu number is" << stu.stu_nu << endl;
}
我们可以看到show函数这个友元函数无需再次声明,只需在test2.cpp文件中包含test2.h文件即可在main函数中调用show函数,show函数定义会自动链接到main函数。
但其实也存在一种特殊情况,在文章最后说明。
test2.cpp文件
#include <iostream>
#include "test2.h"
using namespace std;
int main()
{
class Student st1("xiaoming", 100001);
show(st1);
print(st1);
Student::print_static(st1);
}
Student::Student(string name, int nu)
{
this->name = name;
stu_nu = nu;
}
结果为:
name is xiaoming
stu number is100001
name isxiaoming
stu number is 100001
name isxiaoming
stu number is 100001
输出结果表明,三种方法都可以访问到类中的私有成员。
友元函数需要二次声明的特殊情况(类内部和外部都要声明):
类模板中,非运算符重载的友元函数如果将定义和声明分开写的话,需要在模板类声明之前加上友元函数的声明,运算符重载友元函数除外。但着我们要尽量避免使用这种情况,尽量遵循一个原则:即除了'>>' '<<'运算符外,尽量避免使用友元函数,即尽量使用非运算符重载的友元函数。
详见: