1.为什么要有友元函数,是为了解决申明问题?
所谓的友元函数就是为了解决一个当A类中有私有成员时,B类取访问他只能通过A类中的接口取访问,会造成如下麻烦:
class A { public: int gethour() {return hour;} int getmin() {return min;} int getsec() {return sec;} private: int hour; int min; int sec; }; class B { public: void prin(A a) { cout<<a.gethour()<<a.getmin()<<a.getsec()<<endl; } };
B类想去访问A类中的hour、min、sec只能通过A类中的接口gethour等接口,如果B类中调用一百次,那A类就要被掉100次,太麻烦了,于是就想出了友元。
2.于是就提出了一个问题:能不能直接访问到A类中的私有成员:
class A { public: int gethour() {return hour;} int getmin() {return min;} int getsec() {return sec;} private: int hour; int min; int sec; }; class B { public: void prin(A a) { cout<<a.hour<<a.min<<a.sec<<endl; } };
这样来访问,那这样肯定编译不过,因为hour、min、sec都是私有的,在类外不能直接访问
3.那如何让他能编译过呢
class A { public: int gethour() {return hour;} int getmin() {return min;} int getsec() {return sec;} friend void B::prin(); private: int hour; int min; int sec; }; class B { public: void prin(A a) { cout<<a.hour<<a.min<<a.sec<<endl; }, };
这样还是报错,因为在A类中用了B类,而此时B类还没定义呢,那该申明解决呢
4.很多人想到的解决方法是在A类的前面申明B类
class B; class A { public: int gethour() {return hour;} int getmin() {return min;} int getsec() {return sec;} friend void B::prin(); private: int hour; int min; int sec; }; class B { public: void prin(A a) { cout<<a.hour<<a.min<<a.sec<<endl; }, };
很明确的告诉你,这样是不行的,为什么呢
因为申明类用class B;这样叫不完全申明,所谓的不完全申明指的是申明B,但是不知道B所占的空间,更不知道B里面有什么成员变量及成员函数,所以在A类中依然不能使用B的恒源函数。
5.那怎么办呢,把B类整个搬到A的前面去,并且申明A类
class A; class B { public: void prin(A a) { cout<<a.hour<<a.min<<a.sec<<endl; }, }; class A { public: int gethour() {return hour;} int getmin() {return min;} int getsec() {return sec;} friend void B::prin(); private: int hour; int min; int sec; };
这样也是会报错,上面见过了此处B类还不知道A类的里面有啥
6.所以就把B类中的prin函数搬到可以看到A中有什么的地方去不就好了。
class A; class B { public: void prin(A a); }; class A { public: int gethour() {return hour;} int getmin() {return min;} int getsec() {return sec;} friend void B::prin(); private: int hour; int min; int sec; }; void B::prin(A a); { cout<<a.hour<<a.min<<a.sec<<endl; }