friend关键字用于声明类的友元,友元可以无视类中成员的属性,无论成员是public、protected或是private,友元类或者友元函数都可以访问,这完全破坏了面向对象编程中封装性的概念。C++11对friend关键字进行了一些改进,先看如下代码
class Poly;
typedef Poly P;
class LiLei {
friend class Poly; //C++98通过, C++11通过
};
class Jim {
friend Poly; //C++98失败, C++11通过
};
class HanMeimei {
friend P; //C++98失败, C++11通过
};
可以看出C++11中,声明一个类为另外一个类的友元时,不再需要class关键字,甚至使用别名也是可以的。
这个改进的一个作用就是,可以为类模板声明友元了,如下的代码在C++98中是做不到的:
class P;
template <typename T> class People {
friend T;
};
People<P> PP; // 类型P在这里是People类型的友元了
People<int> Pi; // 对于int类型模板参数,友元声明被忽略
下面是个例子,说明了类模板友元的用处,做单元测试的时候,可以访问private变量
template<typename T> class TargetT {
public:
friend T;
void run(int a, int b){
x = x + a;
y = y + b;
}
private:
int x = 0;
int y = 0;
};
#ifdef UNIT_TEST
class Validator {
public:
void validate(int a, int b, TargetT & t) {
}
};
int main(){
TargetT<Validator> target;
target.run(1, 2);
Validator v;
v.validate(1, 2, target);
return 0;
}
#endif