友元
一般来说,类内的私有数据是对外不可见的,但在有些情况下,我们需要在类外对该类的私有数据进行访问,这就需要用到一种新技术——友元
(friend),即在声明前添加关键字friend
。
友元关系是单向的,即如果A是B的友元,但B不一定是A的友元;
友元关系无传递性,即如果A是B的友元,B是C的友元,但A不一定是C的友元。
1. 友元函数
友元函数是指某些非类成员函数,但可以访问类内的私有数据。
#include <iostream>
using namespace std;class A {
private:int data;
public:A() : data(1) {}friend void show( const A& t ); //添加friend定义友元函数
}; /* 友元函数在类外声明时不加friend */
void show( const A& t ) {cout << "data = " << t.data << endl;
}int main(void) { A a;show(a); return 0;
}/*运行结果:
data = 1*/
2. 友元类
友元类是指若需要在类B中直接访问类A的私有数据,因此将B作为A的友元(在A中声明friend class B;
)。
友元类中的成员函数、私有数据都可以在另一个类中被使用(即类B中可以直接使用类A的私有数据等)
class Tv {
private: int state;
public: friend class Remote; //声明Remote为Tv的友元类enum{ Off, On };Tv( int s = Off ) : state(s) {}void onoff() { state = (state == On) ? Off : On; }
};class Remote {
public: void onoff( Tv & t ) { t.onoff(); }
};
3. 友元成员函数
友元成员函数是指类中的一个成员函数被定义为友元函数。
与友元类不同的是,只有友元成员函数可以在另一个中被使用,其余函数都不可以。
#include <iostream>
using namespace std;class B; //前向声明class A{
private: int a;
public: A() { a = 1; }void print( B & b );
};/* 示例位置1 */class B{
private: int b;
public: B() { b = 6; }void print() { cout << b << endl; }friend void A::print( B & b ); //友元成员函数
};/* 被定义为友元成员函数的函数必须在类外(另一个使用该函数的类后面)定义 */
void A::print( B & b ) {cout << "b = " << b.b << endl;
}int main() {A a;B b;a.print( b );return 0;
}/*输出结果:
b = 6*/
需要注意的是:
(1)类的前向声明。由于在A中的print函数需要使用B,如果不进行B的前向声明,编译器就不知道B是一个类,会报错。
(2)类的排列顺序。在类B中会用到A的方法print(),因此需要先定义A,再定义B。
(3)友元成员函数的定义位置。友元成员函数不能使用内联代码,类中只能有函数声明。函数定义需要放到类之后,在类外进行定义,而且必须放到另一个类定义的后面。(对上面代码来说,若将A::print()的定义放在类B定义之前——示例位置1处,也会报错,提示类B未完成)
对于友元的位置在何处生明,可以简单记为friend在哪,哪个就可以被外面直接访问。(friend在类A,A就可以被其他特定位置访问)