友元
对于一个类来说,类外部的对象想要访问类中的private
成员只有通过公共访问函数来实现。这在有些时候会很不方便,这个时候就可以使用友元的方式使一些特定的外部对象也能访问类内的private
成员。友元分为三种,分别为友元函数
,友元类
和友元成员函数
。
友元函数
如果一个类将一个函数声明为自己的友元函数,则表示该函数能够直接访问本类中的私有成员。声明函数为友元函数在类的声明中完成,而函数的定义跟普通函数一样,不需要额外修改。并且同一个函数可以同时是多个类的友元函数,例如:
class Fractor; //Stock类中用到了Fractor类,所以需要先声明
class Stock{
private:
double price;
public:
Stock(double p){
price = p;
}
Stock();
friend Stock & operator*(Stock &, const Fractor &);
};
class Fractor{
private:
double val;
public:
Fractor(){};
Fractor(double v){
val = v;
}
friend Stock & operator*(Stock &, const Fractor &);
};
Stock & operator*(Stock & s, const Fractor & f){
s.price *= f.val;
return s;
}
Stock s(2);
Fractor f(3);
Stock & d = s * f; //这里s跟f的顺序不能互换,必须严格遵守函数中的顺序
友元类
直接让一个类成为自己的友元类,使得友元类中的所有成员都可以访问自己的private
成员。
class A{
private:
int a;
//也可以在private中声明,声明位置没有要求
//friend class B;
public:
A(int x): a(x){}
//代码到这里B类还没有定义,但是还是可以照常声明,因为语句已经说明了B是一个类
friend class B;
};
class B{
private:
int b;
public:
B(int x): b(x){}
void printA(A);
};
void B::printA(A a){
cout << a.a << endl;
}
声明友元类的时候,声明位置没有要求,可以在private
内声明,也可以在public
内声明,效果都是一样的。
声明友元类的时候不需要事先声明没有定义的类,直接声明即可,因为friend class B
已经说明了B
是一个语句。
友元成员函数
class A;
class B{
private:
int b;
public:
B(int x): b(x){}
void printA(A);
};
class A{
private:
int a;
//也可以在private中声明,声明位置没有要求
//friend class B;
public:
A(int x): a(x){}
friend void B::printA(A);
};
A a(1);
B b(2);
b.printA(a);
让目标类的部分方法能访问自己的private
成员,使用域解析符
指定目标类中的方法即可。但是要注意友元成员函数一般会造成循环依赖,所以要注意提前声明还没有定义的类。
两个类的定义顺序也有要求,如果A
在B
前已经声明了,那么在A
中声明friend void B::printA(A)
就会有错误,因为编译器这时还不知道B
中是否有printA(A)
这个函数。