C++友元

来源:互联网 发布:centos kvm使用 编辑:程序博客网 时间:2024/05/30 23:48

</pre></p><pre name="code" class="cpp">

友元有友元类,友元成员函数,友元函数三种。

1、什么是友元?

官方解释:允许一个类将对其非公有成员的访问权授予指定的类或函数(分别是友元类和C++友元函数)。

自己解释:①友元从“友”字看出这个关系,友元类就是A类是B类的朋友,B类就充分了解A类,所以能访问A类中的成员变量与成员函数(B类若跟A类没关系,这样原本是不可以的,C++为了保护数据,隐藏细节,连返回类中的数据成员都要封装成一个函数,就是怕你直接访问内部数据乱搞,当然直接访问也是可以的,只是一般不这么做!现在B成了A的朋友,所以B能直接访问A)。注意,指定了A是B的朋友,不代表B是A的朋友,也就是说B的情况A是不了解的(生活就是这么现实!!)②友元成员函数,跟友元类相比,可访问范围变小了。我们指定的是A中的某个成员函数是B类的朋友,所以B类就能访问A类的所指定的成员函数(包括私有权限的成员函数)。③友元函数,这个从字面上看没有任何跟类有关的字眼(既不是类,也不是成员),它是类的非成员函数!这个非成员函数其实就是学C语言的时候所定义过的函数,总之就不是类里的。而同样加上了友元的字眼,这个函数就能访问它所指定的类的私有数据。具体怎么指定,请往下看!


2、如何使用友元?

使用关键字 friend,就可以到处找好基友了~~~

示例1、使用友元类

//----mytime.h#ifndef MYTIME_H_#define MYTIME_H_class MyTime{<span></span>//friend void Remote::setTime(MyTime &otime,MyTime &ntime);<span></span>//使用友元成员函数<span></span><span></span>friend class Remote;<span></span>//使用友元类<span></span>private:<span></span>int hours;<span></span>int minutes;<span></span>int seconds;<span></span>public:<span></span>MyTime (int h=0,int m=0,int s=0){hours=h;minutes=m;seconds=s;};<span></span>MyTime (MyTime &time) {hours=time.hours;minutes=time.minutes;seconds=time.seconds;};<span></span>~MyTime(){};<span></span>//<span></span>bool setTime(int h,int m,int s){hours=h;minutes=m;seconds=s;};<span></span>void showtime(){std::cout<<"hours : "<<hours<<"minutes : "<<minutes << std::endl;};<span></span><span></span>MyTime operator *(const int &t) const;<span></span>friend MyTime operator *(int k,const MyTime &t);<span></span>//使用友元函数<span></span>};class Remote<span></span>//遥控类,可以设置时间{<span></span>public:<span></span>//构造函数一定要在前面加public 否则默认都是private<span></span>Remote (int m){i=m;};<span></span><span></span>~Remote(){};<span></span>void setTime(MyTime &otime,MyTime &ntime){ntime.hours=otime.hours;ntime.minutes=otime.minutes;ntime.seconds=otime.seconds;};<span></span>private:<span></span>int i;};MyTime MyTime::operator *(const int &t) const{<span></span>MyTime result;<span></span>long totalminutes = hours*t*60+minutes*t;<span></span>result.hours = totalminutes/60;<span></span>result.minutes = totalminutes%60;<span></span>return result;}MyTime operator *(int k,const MyTime &t){<span></span>return t*k;}#endif
</pre><p></p><div>示例2、使用友元成员函数:</div><p></p><p></p><pre name="code" class="cpp"><pre name="code" class="cpp">
//----mytime.h#ifndef MYTIME_H_#define MYTIME_H_class MyTime;<span style="white-space:pre"></span>//前置声明class Remote<span></span>//遥控类,可以设置时间{<span></span>public:<span></span>//构造函数一定要在前面加public 否则默认都是private<span></span>Remote (int m){i=m;};<span></span><span></span>~Remote(){};<span></span>void setTime(MyTime &otime,MyTime &ntime);<span></span>private:<span></span>int i;};class MyTime{<span></span>friend void Remote::setTime(MyTime &otime,MyTime &ntime);<span></span>//使用友元成员函数<span></span><span></span>//friend class Remote;<span></span>private:<span></span>int hours;<span></span>int minutes;<span></span>int seconds;<span></span>public:<span></span>MyTime (int h=0,int m=0,int s=0){hours=h;minutes=m;seconds=s;};<span></span>MyTime (MyTime &time) {hours=time.hours;minutes=time.minutes;seconds=time.seconds;};<span></span>~MyTime(){};<span></span>//<span></span>bool setTime(int h,int m,int s){hours=h;minutes=m;seconds=s;};<span></span>void showtime(){std::cout<<"hours : "<<hours<<"minutes : "<<minutes << std::endl;};<span></span><span></span>MyTime operator *(const int &t) const;<span></span>friend MyTime operator *(int k,const MyTime &t);<span></span>//使用友元函数<span></span>//const型成员函数,const型对象只能访问const型成员函数};void Remote::setTime(MyTime &otime,MyTime &ntime){<span></span>ntime.hours=otime.hours;<span></span>ntime.minutes=otime.minutes;<span></span>ntime.seconds=otime.seconds;}MyTime MyTime::operator *(const int &t) const{<span></span>MyTime result;<span></span>long totalminutes = hours*t*60+minutes*t;<span></span>result.hours = totalminutes/60;<span></span>result.minutes = totalminutes%60;<span></span>return result;}MyTime operator *(int k,const MyTime &t){<span></span>return t*k;}#endif

成员函数的已经包括在这里面了

<span style="font-family: Arial, Helvetica, sans-serif;"></span><span style="font-family: Arial, Helvetica, sans-serif;">friend MyTime operator *(int k,const MyTime &t);</span><span style="font-family: Arial, Helvetica, sans-serif;"></span><span style="font-family: Arial, Helvetica, sans-serif;">//使用友元函数</span><span style="font-family: Arial, Helvetica, sans-serif;"></span>
就是这句

测试代码:

//--------mytime.cpp#include <iostream>#include "mytime.h"int main(){MyTime time(1,1,2);MyTime time2 =2*time;time2.showtime();Remote remote(1);remote.setTime(time,time2);time.showtime();return 0;}

输出:



3、实际应用

友元运算符重载:


class X{//运算符重载——友元函数private:int x;public:X(int m){x=m;};X(X &y){x=y.get();};~X(){};int get(){return x;};void set(int y){x=y;};friend std::ostream & operator << (X &x1,std::ostream &os){os<<"friend 1os:"<<x1.x;return os;  };<span style="white-space:pre"></span>//第一个友元函数<span style="white-space:pre"></span>//友元函数,不是类的成员函数 friend std::ostream & operator << (std::ostream &os,X &x1){os<<"friend 2os:"<<x1.x;return os;  }};

int main(){X x(1);//x.operator<<(y,std::cout);//重载<<的一些尝试<span style="white-space:pre"></span>std::cout<<x;<span style="white-space:pre"></span>//调用第二个<span style="white-space:pre"></span>x<<std::cout;<span style="white-space:pre"></span>//调用第一个return 0;}
测试输出:



<pre name="code" class="cpp">

可以看出
std::cout<<x;
调用的是
 friend std::ostream & operator << (std::ostream &os,X &x1){os<<"friend 2os:"<<x1.x;return os;  }
至于为什么是这样,我也没找到答案,但是直观看就应该是这样,估计是编译器的事了!

就像为什么重载 << 要用 operator << 这样做为约定一样!


<pre name="code" class="cpp">

0 0